@iqai/adk 0.8.0 → 0.8.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/CHANGELOG.md +49 -0
- package/README.md +2 -2
- package/dist/constants.d.mts +2 -2
- package/dist/constants.d.ts +2 -2
- package/dist/constants.js +1 -1
- package/dist/constants.mjs +1 -1
- package/dist/index.d.mts +79 -50
- package/dist/index.d.ts +79 -50
- package/dist/index.js +391 -127
- package/dist/index.mjs +391 -127
- package/package.json +10 -4
package/dist/index.js
CHANGED
|
@@ -1604,12 +1604,21 @@ var InvocationContext = class _InvocationContext {
|
|
|
1604
1604
|
* The current session of this invocation context. Readonly.
|
|
1605
1605
|
*/
|
|
1606
1606
|
session;
|
|
1607
|
+
/**
|
|
1608
|
+
* Shared flags container so that child/parent contexts stay in sync.
|
|
1609
|
+
*/
|
|
1610
|
+
_invocationFlags;
|
|
1607
1611
|
/**
|
|
1608
1612
|
* Whether to end this invocation.
|
|
1609
1613
|
*
|
|
1610
1614
|
* Set to True in callbacks or tools to terminate this invocation.
|
|
1611
1615
|
*/
|
|
1612
|
-
endInvocation
|
|
1616
|
+
get endInvocation() {
|
|
1617
|
+
return this._invocationFlags.endInvocation;
|
|
1618
|
+
}
|
|
1619
|
+
set endInvocation(value) {
|
|
1620
|
+
this._invocationFlags.endInvocation = value;
|
|
1621
|
+
}
|
|
1613
1622
|
/**
|
|
1614
1623
|
* The queue to receive live requests.
|
|
1615
1624
|
*/
|
|
@@ -1650,7 +1659,9 @@ var InvocationContext = class _InvocationContext {
|
|
|
1650
1659
|
this.agent = options.agent;
|
|
1651
1660
|
this.userContent = options.userContent;
|
|
1652
1661
|
this.session = options.session;
|
|
1653
|
-
this.
|
|
1662
|
+
this._invocationFlags = options.invocationFlags ?? {
|
|
1663
|
+
endInvocation: options.endInvocation || false
|
|
1664
|
+
};
|
|
1654
1665
|
this.liveRequestQueue = options.liveRequestQueue;
|
|
1655
1666
|
this.activeStreamingTools = options.activeStreamingTools;
|
|
1656
1667
|
this.transcriptionCache = options.transcriptionCache;
|
|
@@ -1709,6 +1720,12 @@ var InvocationContext = class _InvocationContext {
|
|
|
1709
1720
|
getSpanCounters() {
|
|
1710
1721
|
return this._spanCounters;
|
|
1711
1722
|
}
|
|
1723
|
+
/**
|
|
1724
|
+
* Exposes shared invocation flags for child contexts.
|
|
1725
|
+
*/
|
|
1726
|
+
getInvocationFlags() {
|
|
1727
|
+
return this._invocationFlags;
|
|
1728
|
+
}
|
|
1712
1729
|
/**
|
|
1713
1730
|
* Creates a child invocation context for a sub-agent
|
|
1714
1731
|
*/
|
|
@@ -1727,7 +1744,7 @@ var InvocationContext = class _InvocationContext {
|
|
|
1727
1744
|
// Update to the new agent
|
|
1728
1745
|
userContent: this.userContent,
|
|
1729
1746
|
session: this.session,
|
|
1730
|
-
|
|
1747
|
+
invocationFlags: this._invocationFlags,
|
|
1731
1748
|
liveRequestQueue: this.liveRequestQueue,
|
|
1732
1749
|
activeStreamingTools: this.activeStreamingTools,
|
|
1733
1750
|
transcriptionCache: this.transcriptionCache,
|
|
@@ -3943,15 +3960,10 @@ var VectorStorageProvider = class {
|
|
|
3943
3960
|
this.memoryCache.delete(id);
|
|
3944
3961
|
}
|
|
3945
3962
|
} else {
|
|
3946
|
-
const
|
|
3963
|
+
const vectorFilter = this.buildDeleteFilter(filter);
|
|
3964
|
+
deleted = await this.vectorStore.delete({ filter: vectorFilter });
|
|
3947
3965
|
for (const [id, record] of this.memoryCache.entries()) {
|
|
3948
3966
|
if (this.matchesFilter(record, filter)) {
|
|
3949
|
-
idsToDelete.push(id);
|
|
3950
|
-
}
|
|
3951
|
-
}
|
|
3952
|
-
if (idsToDelete.length > 0) {
|
|
3953
|
-
deleted = await this.vectorStore.delete({ ids: idsToDelete });
|
|
3954
|
-
for (const id of idsToDelete) {
|
|
3955
3967
|
this.memoryCache.delete(id);
|
|
3956
3968
|
}
|
|
3957
3969
|
}
|
|
@@ -3962,6 +3974,10 @@ var VectorStorageProvider = class {
|
|
|
3962
3974
|
* Count memories matching filter.
|
|
3963
3975
|
*/
|
|
3964
3976
|
async count(filter) {
|
|
3977
|
+
if (this.vectorStore.count) {
|
|
3978
|
+
const vectorFilter = this.buildDeleteFilter(filter);
|
|
3979
|
+
return this.vectorStore.count(vectorFilter);
|
|
3980
|
+
}
|
|
3965
3981
|
let count = 0;
|
|
3966
3982
|
for (const record of this.memoryCache.values()) {
|
|
3967
3983
|
if (this.matchesFilter(record, filter)) {
|
|
@@ -4093,15 +4109,34 @@ var VectorStorageProvider = class {
|
|
|
4093
4109
|
}
|
|
4094
4110
|
return filter;
|
|
4095
4111
|
}
|
|
4112
|
+
/**
|
|
4113
|
+
* Build filter object for vector store delete/count operations.
|
|
4114
|
+
*/
|
|
4115
|
+
buildDeleteFilter(filter) {
|
|
4116
|
+
const vectorFilter = {};
|
|
4117
|
+
if (filter.userId !== void 0) vectorFilter.userId = filter.userId;
|
|
4118
|
+
if (filter.appName !== void 0) vectorFilter.appName = filter.appName;
|
|
4119
|
+
if (filter.sessionId !== void 0)
|
|
4120
|
+
vectorFilter.sessionId = filter.sessionId;
|
|
4121
|
+
if (filter.before !== void 0) vectorFilter.before = filter.before;
|
|
4122
|
+
if (filter.after !== void 0) vectorFilter.after = filter.after;
|
|
4123
|
+
if (this.namespace) vectorFilter.namespace = this.namespace;
|
|
4124
|
+
return vectorFilter;
|
|
4125
|
+
}
|
|
4096
4126
|
/**
|
|
4097
4127
|
* Check if a record matches the given filter.
|
|
4098
4128
|
*/
|
|
4099
4129
|
matchesFilter(record, filter) {
|
|
4100
|
-
if (filter.userId && record.userId !== filter.userId)
|
|
4101
|
-
|
|
4102
|
-
if (filter.
|
|
4103
|
-
|
|
4104
|
-
if (filter.
|
|
4130
|
+
if (filter.userId !== void 0 && record.userId !== filter.userId)
|
|
4131
|
+
return false;
|
|
4132
|
+
if (filter.appName !== void 0 && record.appName !== filter.appName)
|
|
4133
|
+
return false;
|
|
4134
|
+
if (filter.sessionId !== void 0 && record.sessionId !== filter.sessionId)
|
|
4135
|
+
return false;
|
|
4136
|
+
if (filter.before !== void 0 && record.timestamp > filter.before)
|
|
4137
|
+
return false;
|
|
4138
|
+
if (filter.after !== void 0 && record.timestamp < filter.after)
|
|
4139
|
+
return false;
|
|
4105
4140
|
return true;
|
|
4106
4141
|
}
|
|
4107
4142
|
/**
|
|
@@ -4308,11 +4343,12 @@ var LlmSummaryProvider = class {
|
|
|
4308
4343
|
}
|
|
4309
4344
|
const baseUrl = this.baseUrl ?? "https://generativelanguage.googleapis.com/v1beta";
|
|
4310
4345
|
const response = await fetch(
|
|
4311
|
-
`${baseUrl}/models/${this.model}:generateContent
|
|
4346
|
+
`${baseUrl}/models/${this.model}:generateContent`,
|
|
4312
4347
|
{
|
|
4313
4348
|
method: "POST",
|
|
4314
4349
|
headers: {
|
|
4315
|
-
"Content-Type": "application/json"
|
|
4350
|
+
"Content-Type": "application/json",
|
|
4351
|
+
"x-goog-api-key": apiKey
|
|
4316
4352
|
},
|
|
4317
4353
|
body: JSON.stringify({
|
|
4318
4354
|
contents: [{ parts: [{ text: prompt }] }],
|
|
@@ -4689,7 +4725,7 @@ var OPERATIONS = {
|
|
|
4689
4725
|
EXECUTE_TOOL: "execute_tool",
|
|
4690
4726
|
// ============================================
|
|
4691
4727
|
// ADK-specific operations (framework extensions)
|
|
4692
|
-
// These are non-standard but useful for the ADK framework
|
|
4728
|
+
// These are non-standard but useful for the ADK-TS framework
|
|
4693
4729
|
// ============================================
|
|
4694
4730
|
TRANSFER_AGENT: "transfer_agent",
|
|
4695
4731
|
// Multi-agent transfer
|
|
@@ -5784,7 +5820,7 @@ var TracingService = class {
|
|
|
5784
5820
|
[ADK_ATTRS.INVOCATION_ID]: invocationContext.invocationId,
|
|
5785
5821
|
[ADK_ATTRS.EVENT_ID]: eventId,
|
|
5786
5822
|
[ADK_ATTRS.ENVIRONMENT]: getEnvironment() || "",
|
|
5787
|
-
// Content attributes (only if capture is enabled) - ADK namespace for backward compat
|
|
5823
|
+
// Content attributes (only if capture is enabled) - ADK-TS namespace for backward compat
|
|
5788
5824
|
[ADK_ATTRS.LLM_REQUEST]: captureContent ? safeJsonStringify(llmRequestData) : "{}",
|
|
5789
5825
|
[ADK_ATTRS.LLM_RESPONSE]: captureContent ? safeJsonStringify(llmResponseData) : "{}"
|
|
5790
5826
|
});
|
|
@@ -6483,7 +6519,7 @@ var BaseLlm = class {
|
|
|
6483
6519
|
true
|
|
6484
6520
|
// retry may be recommended for transient model errors
|
|
6485
6521
|
);
|
|
6486
|
-
this.logger.error("\u274C ADK LLM Error:", {
|
|
6522
|
+
this.logger.error("\u274C ADK-TS LLM Error:", {
|
|
6487
6523
|
model: this.model,
|
|
6488
6524
|
error: error.message
|
|
6489
6525
|
});
|
|
@@ -7251,7 +7287,7 @@ var AiSdkLlm = class _AiSdkLlm extends BaseLlm {
|
|
|
7251
7287
|
});
|
|
7252
7288
|
}
|
|
7253
7289
|
/**
|
|
7254
|
-
* Convert ADK LlmRequest to AI SDK CoreMessage format
|
|
7290
|
+
* Convert ADK-TS LlmRequest to AI SDK CoreMessage format
|
|
7255
7291
|
*/
|
|
7256
7292
|
convertToAiSdkMessages(llmRequest) {
|
|
7257
7293
|
const messages = [];
|
|
@@ -7301,7 +7337,7 @@ var AiSdkLlm = class _AiSdkLlm extends BaseLlm {
|
|
|
7301
7337
|
return transformedSchema;
|
|
7302
7338
|
}
|
|
7303
7339
|
/**
|
|
7304
|
-
* Convert ADK tools to AI SDK tools format
|
|
7340
|
+
* Convert ADK-TS tools to AI SDK tools format
|
|
7305
7341
|
*/
|
|
7306
7342
|
convertToAiSdkTools(llmRequest) {
|
|
7307
7343
|
const tools = {};
|
|
@@ -7322,7 +7358,7 @@ var AiSdkLlm = class _AiSdkLlm extends BaseLlm {
|
|
|
7322
7358
|
return tools;
|
|
7323
7359
|
}
|
|
7324
7360
|
/**
|
|
7325
|
-
* Convert ADK Content to AI SDK CoreMessage
|
|
7361
|
+
* Convert ADK-TS Content to AI SDK CoreMessage
|
|
7326
7362
|
*/
|
|
7327
7363
|
contentToAiSdkMessage(content) {
|
|
7328
7364
|
const role = this.mapRole(content.role);
|
|
@@ -7424,7 +7460,7 @@ var AiSdkLlm = class _AiSdkLlm extends BaseLlm {
|
|
|
7424
7460
|
return { role: "user", content: contentParts };
|
|
7425
7461
|
}
|
|
7426
7462
|
/**
|
|
7427
|
-
* Map ADK role to AI SDK role
|
|
7463
|
+
* Map ADK-TS role to AI SDK role
|
|
7428
7464
|
*/
|
|
7429
7465
|
mapRole(role) {
|
|
7430
7466
|
switch (role) {
|
|
@@ -7438,7 +7474,7 @@ var AiSdkLlm = class _AiSdkLlm extends BaseLlm {
|
|
|
7438
7474
|
}
|
|
7439
7475
|
}
|
|
7440
7476
|
/**
|
|
7441
|
-
* Map AI SDK finish reason to ADK finish reason
|
|
7477
|
+
* Map AI SDK finish reason to ADK-TS finish reason
|
|
7442
7478
|
*/
|
|
7443
7479
|
mapFinishReason(finishReason) {
|
|
7444
7480
|
switch (finishReason) {
|
|
@@ -7457,6 +7493,21 @@ var AiSdkLlm = class _AiSdkLlm extends BaseLlm {
|
|
|
7457
7493
|
// src/models/anthropic-llm.ts
|
|
7458
7494
|
init_logger();
|
|
7459
7495
|
var import_sdk = __toESM(require("@anthropic-ai/sdk"));
|
|
7496
|
+
|
|
7497
|
+
// src/models/llm-utils.ts
|
|
7498
|
+
function safeParseToolArgs(json, logger2) {
|
|
7499
|
+
try {
|
|
7500
|
+
return JSON.parse(json || "{}");
|
|
7501
|
+
} catch (error) {
|
|
7502
|
+
logger2.warn("Failed to parse tool call arguments, using empty args", {
|
|
7503
|
+
rawArgs: json,
|
|
7504
|
+
error: String(error)
|
|
7505
|
+
});
|
|
7506
|
+
return {};
|
|
7507
|
+
}
|
|
7508
|
+
}
|
|
7509
|
+
|
|
7510
|
+
// src/models/anthropic-llm.ts
|
|
7460
7511
|
var DEFAULT_MAX_OUTPUT_TOKENS = 1024;
|
|
7461
7512
|
var THOUGHT_OPEN_TAGS = [
|
|
7462
7513
|
"<thinking>",
|
|
@@ -7662,7 +7713,7 @@ var AnthropicLlm = class extends BaseLlm {
|
|
|
7662
7713
|
functionCall: {
|
|
7663
7714
|
id: block.id,
|
|
7664
7715
|
name: block.name,
|
|
7665
|
-
args:
|
|
7716
|
+
args: safeParseToolArgs(block.inputJson, this.logger)
|
|
7666
7717
|
}
|
|
7667
7718
|
});
|
|
7668
7719
|
}
|
|
@@ -7714,7 +7765,7 @@ var AnthropicLlm = class extends BaseLlm {
|
|
|
7714
7765
|
throw new Error(`Live connection is not supported for ${this.model}.`);
|
|
7715
7766
|
}
|
|
7716
7767
|
/**
|
|
7717
|
-
* Convert Anthropic Message to ADK LlmResponse
|
|
7768
|
+
* Convert Anthropic Message to ADK-TS LlmResponse
|
|
7718
7769
|
*/
|
|
7719
7770
|
anthropicMessageToLlmResponse(message) {
|
|
7720
7771
|
this.logger.debug(
|
|
@@ -7742,7 +7793,7 @@ var AnthropicLlm = class extends BaseLlm {
|
|
|
7742
7793
|
});
|
|
7743
7794
|
}
|
|
7744
7795
|
/**
|
|
7745
|
-
* Convert ADK Content to Anthropic MessageParam
|
|
7796
|
+
* Convert ADK-TS Content to Anthropic MessageParam
|
|
7746
7797
|
*/
|
|
7747
7798
|
contentToAnthropicMessage(content) {
|
|
7748
7799
|
return {
|
|
@@ -7753,39 +7804,39 @@ var AnthropicLlm = class extends BaseLlm {
|
|
|
7753
7804
|
};
|
|
7754
7805
|
}
|
|
7755
7806
|
/**
|
|
7756
|
-
* Convert ADK Part to Anthropic content block
|
|
7807
|
+
* Convert ADK-TS Part to Anthropic content block
|
|
7757
7808
|
*/
|
|
7758
7809
|
partToAnthropicBlock(part) {
|
|
7759
7810
|
if (part.text) return { type: "text", text: part.text };
|
|
7760
|
-
if (part.
|
|
7811
|
+
if (part.functionCall)
|
|
7761
7812
|
return {
|
|
7762
7813
|
type: "tool_use",
|
|
7763
|
-
id: part.
|
|
7764
|
-
name: part.
|
|
7765
|
-
input: part.
|
|
7814
|
+
id: part.functionCall.id || "",
|
|
7815
|
+
name: part.functionCall.name,
|
|
7816
|
+
input: part.functionCall.args || {}
|
|
7766
7817
|
};
|
|
7767
|
-
if (part.
|
|
7818
|
+
if (part.functionResponse)
|
|
7768
7819
|
return {
|
|
7769
7820
|
type: "tool_result",
|
|
7770
|
-
tool_use_id: part.
|
|
7771
|
-
content: String(part.
|
|
7821
|
+
tool_use_id: part.functionResponse.id || "",
|
|
7822
|
+
content: String(part.functionResponse.response?.result || ""),
|
|
7772
7823
|
is_error: false
|
|
7773
7824
|
};
|
|
7774
7825
|
throw new Error("Unsupported part type for Anthropic conversion");
|
|
7775
7826
|
}
|
|
7776
7827
|
/**
|
|
7777
|
-
* Convert Anthropic content block to ADK Part
|
|
7828
|
+
* Convert Anthropic content block to ADK-TS Part
|
|
7778
7829
|
*/
|
|
7779
7830
|
anthropicBlockToPart(block) {
|
|
7780
7831
|
if (block.type === "text") return { text: block.text };
|
|
7781
7832
|
if (block.type === "tool_use")
|
|
7782
7833
|
return {
|
|
7783
|
-
|
|
7834
|
+
functionCall: { id: block.id, name: block.name, args: block.input }
|
|
7784
7835
|
};
|
|
7785
7836
|
throw new Error("Unsupported Anthropic content block type");
|
|
7786
7837
|
}
|
|
7787
7838
|
/**
|
|
7788
|
-
* Convert ADK function declaration to Anthropic tool param
|
|
7839
|
+
* Convert ADK-TS function declaration to Anthropic tool param
|
|
7789
7840
|
*/
|
|
7790
7841
|
functionDeclarationToAnthropicTool(functionDeclaration) {
|
|
7791
7842
|
const properties = {};
|
|
@@ -7805,14 +7856,14 @@ var AnthropicLlm = class extends BaseLlm {
|
|
|
7805
7856
|
};
|
|
7806
7857
|
}
|
|
7807
7858
|
/**
|
|
7808
|
-
* Convert ADK role to Anthropic role format
|
|
7859
|
+
* Convert ADK-TS role to Anthropic role format
|
|
7809
7860
|
*/
|
|
7810
7861
|
toAnthropicRole(role) {
|
|
7811
7862
|
if (role === "model" || role === "assistant") return "assistant";
|
|
7812
7863
|
return "user";
|
|
7813
7864
|
}
|
|
7814
7865
|
/**
|
|
7815
|
-
* Convert Anthropic stop reason to ADK finish reason
|
|
7866
|
+
* Convert Anthropic stop reason to ADK-TS finish reason
|
|
7816
7867
|
*/
|
|
7817
7868
|
toAdkFinishReason(anthropicStopReason) {
|
|
7818
7869
|
if (["end_turn", "stop_sequence", "tool_use"].includes(
|
|
@@ -8407,7 +8458,10 @@ var OpenAiLlm = class extends BaseLlm {
|
|
|
8407
8458
|
functionCall: {
|
|
8408
8459
|
id: toolCall.id,
|
|
8409
8460
|
name: toolCall.function.name,
|
|
8410
|
-
args:
|
|
8461
|
+
args: safeParseToolArgs(
|
|
8462
|
+
toolCall.function.arguments,
|
|
8463
|
+
this.logger
|
|
8464
|
+
)
|
|
8411
8465
|
}
|
|
8412
8466
|
});
|
|
8413
8467
|
}
|
|
@@ -8500,7 +8554,7 @@ var OpenAiLlm = class extends BaseLlm {
|
|
|
8500
8554
|
functionCall: {
|
|
8501
8555
|
id: toolCall.id || "",
|
|
8502
8556
|
name: toolCall.function.name,
|
|
8503
|
-
args:
|
|
8557
|
+
args: safeParseToolArgs(toolCall.function.arguments, this.logger)
|
|
8504
8558
|
}
|
|
8505
8559
|
});
|
|
8506
8560
|
}
|
|
@@ -8519,7 +8573,7 @@ var OpenAiLlm = class extends BaseLlm {
|
|
|
8519
8573
|
});
|
|
8520
8574
|
}
|
|
8521
8575
|
/**
|
|
8522
|
-
* Convert OpenAI message to ADK LlmResponse
|
|
8576
|
+
* Convert OpenAI message to ADK-TS LlmResponse
|
|
8523
8577
|
*/
|
|
8524
8578
|
openAiMessageToLlmResponse(choice, usage) {
|
|
8525
8579
|
const message = choice.message;
|
|
@@ -8534,7 +8588,7 @@ var OpenAiLlm = class extends BaseLlm {
|
|
|
8534
8588
|
functionCall: {
|
|
8535
8589
|
id: toolCall.id,
|
|
8536
8590
|
name: toolCall.function.name,
|
|
8537
|
-
args:
|
|
8591
|
+
args: safeParseToolArgs(toolCall.function.arguments, this.logger)
|
|
8538
8592
|
}
|
|
8539
8593
|
});
|
|
8540
8594
|
}
|
|
@@ -8554,7 +8608,7 @@ var OpenAiLlm = class extends BaseLlm {
|
|
|
8554
8608
|
});
|
|
8555
8609
|
}
|
|
8556
8610
|
/**
|
|
8557
|
-
* Convert ADK Content to OpenAI ChatCompletionMessage
|
|
8611
|
+
* Convert ADK-TS Content to OpenAI ChatCompletionMessage
|
|
8558
8612
|
*/
|
|
8559
8613
|
contentToOpenAiMessage(content) {
|
|
8560
8614
|
const role = this.toOpenAiRole(content.role);
|
|
@@ -8610,7 +8664,7 @@ var OpenAiLlm = class extends BaseLlm {
|
|
|
8610
8664
|
};
|
|
8611
8665
|
}
|
|
8612
8666
|
/**
|
|
8613
|
-
* Convert ADK Part to OpenAI message content
|
|
8667
|
+
* Convert ADK-TS Part to OpenAI message content
|
|
8614
8668
|
*/
|
|
8615
8669
|
partToOpenAiContent(part) {
|
|
8616
8670
|
if (part.text) {
|
|
@@ -8667,7 +8721,7 @@ var OpenAiLlm = class extends BaseLlm {
|
|
|
8667
8721
|
return transformedSchema;
|
|
8668
8722
|
}
|
|
8669
8723
|
/**
|
|
8670
|
-
* Convert ADK function declaration to OpenAI tool
|
|
8724
|
+
* Convert ADK-TS function declaration to OpenAI tool
|
|
8671
8725
|
*/
|
|
8672
8726
|
functionDeclarationToOpenAiTool(functionDeclaration) {
|
|
8673
8727
|
return {
|
|
@@ -8682,7 +8736,7 @@ var OpenAiLlm = class extends BaseLlm {
|
|
|
8682
8736
|
};
|
|
8683
8737
|
}
|
|
8684
8738
|
/**
|
|
8685
|
-
* Convert ADK role to OpenAI role format
|
|
8739
|
+
* Convert ADK-TS role to OpenAI role format
|
|
8686
8740
|
*/
|
|
8687
8741
|
toOpenAiRole(role) {
|
|
8688
8742
|
if (role === "model") {
|
|
@@ -8694,7 +8748,7 @@ var OpenAiLlm = class extends BaseLlm {
|
|
|
8694
8748
|
return "user";
|
|
8695
8749
|
}
|
|
8696
8750
|
/**
|
|
8697
|
-
* Convert OpenAI finish reason to ADK finish reason
|
|
8751
|
+
* Convert OpenAI finish reason to ADK-TS finish reason
|
|
8698
8752
|
*/
|
|
8699
8753
|
toAdkFinishReason(openaiFinishReason) {
|
|
8700
8754
|
switch (openaiFinishReason) {
|
|
@@ -9026,7 +9080,7 @@ var ReadonlyContext = class {
|
|
|
9026
9080
|
// src/agents/callback-context.ts
|
|
9027
9081
|
var CallbackContext = class extends ReadonlyContext {
|
|
9028
9082
|
/**
|
|
9029
|
-
* TODO: make this public for
|
|
9083
|
+
* TODO: make this public for ADK-TS, but private for users.
|
|
9030
9084
|
*/
|
|
9031
9085
|
_eventActions;
|
|
9032
9086
|
_state;
|
|
@@ -9102,7 +9156,7 @@ var ToolContext = class extends CallbackContext {
|
|
|
9102
9156
|
/**
|
|
9103
9157
|
* The function call id of the current tool call. This id was
|
|
9104
9158
|
* returned in the function call event from LLM to identify a function call.
|
|
9105
|
-
* If LLM didn't return this id, ADK will assign one to it. This id is used
|
|
9159
|
+
* If LLM didn't return this id, ADK-TS will assign one to it. This id is used
|
|
9106
9160
|
* to map function call response to the original function call.
|
|
9107
9161
|
*/
|
|
9108
9162
|
functionCallId;
|
|
@@ -9578,7 +9632,7 @@ function mergeParallelFunctionResponseEvents(functionResponseEvents) {
|
|
|
9578
9632
|
}
|
|
9579
9633
|
mergedActions.requestedAuthConfigs = mergedRequestedAuthConfigs;
|
|
9580
9634
|
const mergedEvent = new Event({
|
|
9581
|
-
invocationId:
|
|
9635
|
+
invocationId: baseEvent.invocationId,
|
|
9582
9636
|
author: baseEvent.author,
|
|
9583
9637
|
branch: baseEvent.branch,
|
|
9584
9638
|
content: { role: "user", parts: mergedParts },
|
|
@@ -9630,7 +9684,7 @@ var EnhancedAuthConfig = class {
|
|
|
9630
9684
|
rawAuthCredential;
|
|
9631
9685
|
/**
|
|
9632
9686
|
* Exchanged auth credential after processing
|
|
9633
|
-
* Filled by ADK and client working together
|
|
9687
|
+
* Filled by ADK-TS and client working together
|
|
9634
9688
|
*/
|
|
9635
9689
|
exchangedAuthCredential;
|
|
9636
9690
|
/**
|
|
@@ -10501,7 +10555,7 @@ var FileOperationsTool = class extends BaseTool {
|
|
|
10501
10555
|
async runAsync(args, _context) {
|
|
10502
10556
|
try {
|
|
10503
10557
|
const resolvedPath = this.resolvePath(args.filepath);
|
|
10504
|
-
this.validatePath(resolvedPath);
|
|
10558
|
+
await this.validatePath(resolvedPath);
|
|
10505
10559
|
const encoding = args.encoding || "utf8";
|
|
10506
10560
|
switch (args.operation) {
|
|
10507
10561
|
case "read":
|
|
@@ -10543,15 +10597,38 @@ var FileOperationsTool = class extends BaseTool {
|
|
|
10543
10597
|
return import_node_path3.default.isAbsolute(filepath) ? filepath : import_node_path3.default.resolve(this.basePath, filepath);
|
|
10544
10598
|
}
|
|
10545
10599
|
/**
|
|
10546
|
-
* Validate that a path is within the base path for security
|
|
10600
|
+
* Validate that a path is within the base path for security.
|
|
10601
|
+
* Resolves symlinks to prevent symlink escape attacks.
|
|
10547
10602
|
*/
|
|
10548
|
-
validatePath(filepath) {
|
|
10549
|
-
const
|
|
10550
|
-
const
|
|
10551
|
-
|
|
10552
|
-
|
|
10553
|
-
|
|
10554
|
-
|
|
10603
|
+
async validatePath(filepath) {
|
|
10604
|
+
const realBasePath = await import_promises.default.realpath(this.basePath);
|
|
10605
|
+
const isWithinBase = (p, base) => p === base || p.startsWith(base + import_node_path3.default.sep);
|
|
10606
|
+
try {
|
|
10607
|
+
const realPath = await import_promises.default.realpath(filepath);
|
|
10608
|
+
if (!isWithinBase(realPath, realBasePath)) {
|
|
10609
|
+
throw new Error(
|
|
10610
|
+
"Access denied: Can't access paths outside the base directory"
|
|
10611
|
+
);
|
|
10612
|
+
}
|
|
10613
|
+
} catch (error) {
|
|
10614
|
+
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
10615
|
+
const parentDir = import_node_path3.default.dirname(filepath);
|
|
10616
|
+
let realParent;
|
|
10617
|
+
try {
|
|
10618
|
+
realParent = await import_promises.default.realpath(parentDir);
|
|
10619
|
+
} catch {
|
|
10620
|
+
throw new Error(
|
|
10621
|
+
"Access denied: Can't access paths outside the base directory"
|
|
10622
|
+
);
|
|
10623
|
+
}
|
|
10624
|
+
if (!isWithinBase(realParent, realBasePath)) {
|
|
10625
|
+
throw new Error(
|
|
10626
|
+
"Access denied: Can't access paths outside the base directory"
|
|
10627
|
+
);
|
|
10628
|
+
}
|
|
10629
|
+
} else {
|
|
10630
|
+
throw error;
|
|
10631
|
+
}
|
|
10555
10632
|
}
|
|
10556
10633
|
}
|
|
10557
10634
|
/**
|
|
@@ -10649,7 +10726,7 @@ var FileOperationsTool = class extends BaseTool {
|
|
|
10649
10726
|
const results = await Promise.all(
|
|
10650
10727
|
entries.map(async (entry) => {
|
|
10651
10728
|
const entryPath = import_node_path3.default.join(dirpath, entry.name);
|
|
10652
|
-
const stats = await import_promises.default.
|
|
10729
|
+
const stats = await import_promises.default.lstat(entryPath);
|
|
10653
10730
|
return {
|
|
10654
10731
|
name: entry.name,
|
|
10655
10732
|
path: entryPath,
|
|
@@ -10891,6 +10968,62 @@ var googleSearchArgsSchema = import_zod.z.object({
|
|
|
10891
10968
|
// src/tools/common/http-request-tool.ts
|
|
10892
10969
|
var import_genai8 = require("@google/genai");
|
|
10893
10970
|
init_base_tool();
|
|
10971
|
+
|
|
10972
|
+
// src/tools/utils/url-validation.ts
|
|
10973
|
+
function validateUrlForFetch(urlString) {
|
|
10974
|
+
const url = new URL(urlString);
|
|
10975
|
+
if (url.protocol !== "http:" && url.protocol !== "https:") {
|
|
10976
|
+
throw new Error(
|
|
10977
|
+
`Blocked URL: only http and https protocols are allowed, got ${url.protocol}`
|
|
10978
|
+
);
|
|
10979
|
+
}
|
|
10980
|
+
const hostname = url.hostname.toLowerCase();
|
|
10981
|
+
if (hostname === "localhost" || hostname === "[::1]") {
|
|
10982
|
+
throw new Error("Blocked URL: localhost is not allowed");
|
|
10983
|
+
}
|
|
10984
|
+
const ipv4 = extractIPv4(hostname);
|
|
10985
|
+
if (ipv4 !== null && isPrivateIP(ipv4)) {
|
|
10986
|
+
throw new Error(
|
|
10987
|
+
"Blocked URL: private/internal IP addresses are not allowed"
|
|
10988
|
+
);
|
|
10989
|
+
}
|
|
10990
|
+
if (isPrivateIP(hostname)) {
|
|
10991
|
+
throw new Error(
|
|
10992
|
+
"Blocked URL: private/internal IP addresses are not allowed"
|
|
10993
|
+
);
|
|
10994
|
+
}
|
|
10995
|
+
return url;
|
|
10996
|
+
}
|
|
10997
|
+
function extractIPv4(hostname) {
|
|
10998
|
+
const bare = hostname.replace(/^\[|\]$/g, "");
|
|
10999
|
+
const dottedMatch = bare.match(
|
|
11000
|
+
/^::ffff:(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$/i
|
|
11001
|
+
);
|
|
11002
|
+
if (dottedMatch) return dottedMatch[1];
|
|
11003
|
+
const hexMatch = bare.match(/^::ffff:([0-9a-f]{1,4}):([0-9a-f]{1,4})$/i);
|
|
11004
|
+
if (hexMatch) {
|
|
11005
|
+
const high = Number.parseInt(hexMatch[1], 16);
|
|
11006
|
+
const low = Number.parseInt(hexMatch[2], 16);
|
|
11007
|
+
return `${high >> 8 & 255}.${high & 255}.${low >> 8 & 255}.${low & 255}`;
|
|
11008
|
+
}
|
|
11009
|
+
return null;
|
|
11010
|
+
}
|
|
11011
|
+
function isPrivateIP(hostname) {
|
|
11012
|
+
const match = hostname.match(/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/);
|
|
11013
|
+
if (!match) return false;
|
|
11014
|
+
const [, a, b] = match;
|
|
11015
|
+
const first = Number(a);
|
|
11016
|
+
const second = Number(b);
|
|
11017
|
+
if (first === 0) return true;
|
|
11018
|
+
if (first === 127) return true;
|
|
11019
|
+
if (first === 10) return true;
|
|
11020
|
+
if (first === 172 && second >= 16 && second <= 31) return true;
|
|
11021
|
+
if (first === 192 && second === 168) return true;
|
|
11022
|
+
if (first === 169 && second === 254) return true;
|
|
11023
|
+
return false;
|
|
11024
|
+
}
|
|
11025
|
+
|
|
11026
|
+
// src/tools/common/http-request-tool.ts
|
|
10894
11027
|
var HttpRequestTool = class extends BaseTool {
|
|
10895
11028
|
constructor() {
|
|
10896
11029
|
super({
|
|
@@ -10953,7 +11086,7 @@ var HttpRequestTool = class extends BaseTool {
|
|
|
10953
11086
|
params,
|
|
10954
11087
|
timeout = 1e4
|
|
10955
11088
|
} = args;
|
|
10956
|
-
const urlObj =
|
|
11089
|
+
const urlObj = validateUrlForFetch(url);
|
|
10957
11090
|
if (params) {
|
|
10958
11091
|
Object.entries(params).forEach(([key, value]) => {
|
|
10959
11092
|
urlObj.searchParams.append(key, value);
|
|
@@ -10967,7 +11100,8 @@ var HttpRequestTool = class extends BaseTool {
|
|
|
10967
11100
|
method,
|
|
10968
11101
|
headers: requestHeaders,
|
|
10969
11102
|
body,
|
|
10970
|
-
signal: AbortSignal.timeout(timeout)
|
|
11103
|
+
signal: AbortSignal.timeout(timeout),
|
|
11104
|
+
redirect: "manual"
|
|
10971
11105
|
};
|
|
10972
11106
|
const response = await fetch(urlObj.toString(), options);
|
|
10973
11107
|
const responseHeaders = {};
|
|
@@ -11775,16 +11909,16 @@ var BashTool = class _BashTool extends BaseTool {
|
|
|
11775
11909
|
// filesystem formatting
|
|
11776
11910
|
/dd\s+if=/,
|
|
11777
11911
|
// disk operations
|
|
11778
|
-
/wget.*\|\s*sh/,
|
|
11912
|
+
/wget.*\|\s*(sh|bash)/,
|
|
11779
11913
|
// download and execute
|
|
11780
|
-
/curl.*\|\s*bash/,
|
|
11914
|
+
/curl.*\|\s*(bash|sh)/,
|
|
11781
11915
|
// download and execute
|
|
11782
11916
|
/eval\s+['"`]/,
|
|
11783
11917
|
// eval with strings
|
|
11784
|
-
/base64.*\|\s*sh/,
|
|
11918
|
+
/base64.*\|\s*(sh|bash)/,
|
|
11785
11919
|
// decode and execute
|
|
11786
|
-
/nc\s+-.*e/,
|
|
11787
|
-
// netcat reverse shell
|
|
11920
|
+
/(nc|ncat|netcat)\s+-.*e/,
|
|
11921
|
+
// netcat reverse shell (nc, ncat, netcat)
|
|
11788
11922
|
/\/proc\/.*\/mem/,
|
|
11789
11923
|
// memory access
|
|
11790
11924
|
/iptables/,
|
|
@@ -11795,8 +11929,18 @@ var BashTool = class _BashTool extends BaseTool {
|
|
|
11795
11929
|
// ownership changes
|
|
11796
11930
|
/sudo/,
|
|
11797
11931
|
// privilege escalation
|
|
11798
|
-
/su\s
|
|
11932
|
+
/su\s+/,
|
|
11799
11933
|
// user switching
|
|
11934
|
+
/python[23]?(\.\d+)?\s+-c\s/,
|
|
11935
|
+
// python interpreter execution (python, python3, python3.11, etc.)
|
|
11936
|
+
/node\s+(-e|--eval)[\s=]/,
|
|
11937
|
+
// node interpreter execution (-e and --eval)
|
|
11938
|
+
/perl\s+-e\s/,
|
|
11939
|
+
// perl interpreter execution
|
|
11940
|
+
/ruby\s+-e\s/,
|
|
11941
|
+
// ruby interpreter execution
|
|
11942
|
+
/php\s+-r\s/
|
|
11943
|
+
// php interpreter execution
|
|
11800
11944
|
];
|
|
11801
11945
|
// Special characters that enable command chaining/injection
|
|
11802
11946
|
static DANGEROUS_CHARS = /[;&|`$()<>]/;
|
|
@@ -12574,11 +12718,16 @@ var WebFetchTool = class extends BaseTool {
|
|
|
12574
12718
|
}
|
|
12575
12719
|
async runAsync(args, _context) {
|
|
12576
12720
|
try {
|
|
12721
|
+
validateUrlForFetch(args.url);
|
|
12577
12722
|
const response = await import_axios2.default.get(args.url, {
|
|
12578
12723
|
timeout: 3e4,
|
|
12579
12724
|
maxRedirects: 5,
|
|
12580
12725
|
headers: {
|
|
12581
12726
|
"User-Agent": "Mozilla/5.0 (compatible; ADK/1.0; +http://example.com)"
|
|
12727
|
+
},
|
|
12728
|
+
beforeRedirect: (options) => {
|
|
12729
|
+
const redirectUrl = typeof options.href === "string" ? options.href : `${options.protocol}//${options.hostname}${options.path}`;
|
|
12730
|
+
validateUrlForFetch(redirectUrl);
|
|
12582
12731
|
}
|
|
12583
12732
|
});
|
|
12584
12733
|
const contentType = response.headers["content-type"] || "";
|
|
@@ -12831,7 +12980,7 @@ var tavilySearchResultSchema = import_zod2.z.object({
|
|
|
12831
12980
|
var tavilySearchResponseSchema = import_zod2.z.object({
|
|
12832
12981
|
query: import_zod2.z.string(),
|
|
12833
12982
|
results: import_zod2.z.array(tavilySearchResultSchema),
|
|
12834
|
-
answer: import_zod2.z.string().optional(),
|
|
12983
|
+
answer: import_zod2.z.string().nullable().optional(),
|
|
12835
12984
|
images: import_zod2.z.array(import_zod2.z.object({ url: import_zod2.z.string(), description: import_zod2.z.string().optional() })).optional(),
|
|
12836
12985
|
auto_parameters: import_zod2.z.record(import_zod2.z.any(), import_zod2.z.string()).optional(),
|
|
12837
12986
|
response_time: import_zod2.z.number(),
|
|
@@ -12988,7 +13137,7 @@ var McpSamplingHandler = class {
|
|
|
12988
13137
|
"INVALID_REQUEST_ERROR" /* INVALID_REQUEST_ERROR */
|
|
12989
13138
|
);
|
|
12990
13139
|
}
|
|
12991
|
-
this.logger.debug("Converting MCP request to ADK format");
|
|
13140
|
+
this.logger.debug("Converting MCP request to ADK-TS format");
|
|
12992
13141
|
const adkContents = this.convertMcpMessagesToADK(
|
|
12993
13142
|
mcpParams.messages,
|
|
12994
13143
|
mcpParams.systemPrompt
|
|
@@ -13002,9 +13151,9 @@ var McpSamplingHandler = class {
|
|
|
13002
13151
|
maxOutputTokens: mcpParams.maxTokens
|
|
13003
13152
|
}
|
|
13004
13153
|
});
|
|
13005
|
-
this.logger.debug("Calling ADK sampling handler");
|
|
13154
|
+
this.logger.debug("Calling ADK-TS sampling handler");
|
|
13006
13155
|
const adkResponse = await this.samplingHandler(adkRequest);
|
|
13007
|
-
this.logger.debug("Converting ADK response to MCP format");
|
|
13156
|
+
this.logger.debug("Converting ADK-TS response to MCP format");
|
|
13008
13157
|
const mcpResponse = this.convertADKResponseToMcp(
|
|
13009
13158
|
adkResponse,
|
|
13010
13159
|
requestModel
|
|
@@ -13034,7 +13183,7 @@ var McpSamplingHandler = class {
|
|
|
13034
13183
|
}
|
|
13035
13184
|
}
|
|
13036
13185
|
/**
|
|
13037
|
-
* Convert MCP messages to ADK Content format
|
|
13186
|
+
* Convert MCP messages to ADK-TS Content format
|
|
13038
13187
|
*/
|
|
13039
13188
|
convertMcpMessagesToADK(mcpMessages, systemPrompt) {
|
|
13040
13189
|
const contents = [];
|
|
@@ -13052,7 +13201,7 @@ var McpSamplingHandler = class {
|
|
|
13052
13201
|
return contents;
|
|
13053
13202
|
}
|
|
13054
13203
|
/**
|
|
13055
|
-
* Convert a single MCP message to ADK Content format
|
|
13204
|
+
* Convert a single MCP message to ADK-TS Content format
|
|
13056
13205
|
*/
|
|
13057
13206
|
convertSingleMcpMessageToADK(mcpMessage) {
|
|
13058
13207
|
const adkRole = mcpMessage.role === "assistant" ? "model" : "user";
|
|
@@ -13067,7 +13216,7 @@ var McpSamplingHandler = class {
|
|
|
13067
13216
|
return adkContent;
|
|
13068
13217
|
}
|
|
13069
13218
|
/**
|
|
13070
|
-
* Convert MCP message content to ADK parts format
|
|
13219
|
+
* Convert MCP message content to ADK-TS parts format
|
|
13071
13220
|
*/
|
|
13072
13221
|
convertMcpContentToADKParts(mcpContent) {
|
|
13073
13222
|
const safeText = (value) => typeof value === "string" ? value : "";
|
|
@@ -13120,7 +13269,7 @@ var McpSamplingHandler = class {
|
|
|
13120
13269
|
}
|
|
13121
13270
|
}
|
|
13122
13271
|
/**
|
|
13123
|
-
* Convert ADK response to MCP response format
|
|
13272
|
+
* Convert ADK-TS response to MCP response format
|
|
13124
13273
|
*/
|
|
13125
13274
|
convertADKResponseToMcp(adkResponse, model) {
|
|
13126
13275
|
let responseText = "";
|
|
@@ -13141,7 +13290,7 @@ var McpSamplingHandler = class {
|
|
|
13141
13290
|
model,
|
|
13142
13291
|
// Use the model from the request
|
|
13143
13292
|
role: "assistant",
|
|
13144
|
-
// ADK responses are always from assistant
|
|
13293
|
+
// ADK-TS responses are always from assistant
|
|
13145
13294
|
content: {
|
|
13146
13295
|
type: "text",
|
|
13147
13296
|
text: responseText
|
|
@@ -13151,11 +13300,11 @@ var McpSamplingHandler = class {
|
|
|
13151
13300
|
return mcpResponse;
|
|
13152
13301
|
}
|
|
13153
13302
|
/**
|
|
13154
|
-
* Update the ADK handler
|
|
13303
|
+
* Update the ADK-TS handler
|
|
13155
13304
|
*/
|
|
13156
13305
|
updateHandler(handler) {
|
|
13157
13306
|
this.samplingHandler = handler;
|
|
13158
|
-
this.logger.debug("ADK sampling handler updated");
|
|
13307
|
+
this.logger.debug("ADK-TS sampling handler updated");
|
|
13159
13308
|
}
|
|
13160
13309
|
};
|
|
13161
13310
|
function createSamplingHandler(handler) {
|
|
@@ -13428,13 +13577,13 @@ var McpClientService = class {
|
|
|
13428
13577
|
}
|
|
13429
13578
|
}
|
|
13430
13579
|
/**
|
|
13431
|
-
* Set a new ADK sampling handler
|
|
13580
|
+
* Set a new ADK-TS sampling handler
|
|
13432
13581
|
*/
|
|
13433
13582
|
setSamplingHandler(handler) {
|
|
13434
13583
|
this.mcpSamplingHandler = new McpSamplingHandler(handler);
|
|
13435
13584
|
if (this.client) {
|
|
13436
13585
|
this.setupSamplingHandler(this.client).catch((error) => {
|
|
13437
|
-
this.logger.error("Failed to update ADK sampling handler:", error);
|
|
13586
|
+
this.logger.error("Failed to update ADK-TS sampling handler:", error);
|
|
13438
13587
|
});
|
|
13439
13588
|
}
|
|
13440
13589
|
}
|
|
@@ -14017,6 +14166,9 @@ var McpToolset = class {
|
|
|
14017
14166
|
}
|
|
14018
14167
|
return true;
|
|
14019
14168
|
}
|
|
14169
|
+
isCacheEnabled() {
|
|
14170
|
+
return this.config.cacheConfig?.enabled !== false;
|
|
14171
|
+
}
|
|
14020
14172
|
/**
|
|
14021
14173
|
* Initializes the client service and establishes a connection.
|
|
14022
14174
|
*/
|
|
@@ -14035,9 +14187,9 @@ var McpToolset = class {
|
|
|
14035
14187
|
}
|
|
14036
14188
|
/**
|
|
14037
14189
|
* Set a sampling handler for this MCP toolset.
|
|
14038
|
-
* This allows MCP servers to request LLM completions through your ADK agent.
|
|
14190
|
+
* This allows MCP servers to request LLM completions through your ADK-TS agent.
|
|
14039
14191
|
*
|
|
14040
|
-
* @param handler - ADK sampling handler that receives ADK-formatted messages
|
|
14192
|
+
* @param handler - ADK-TS sampling handler that receives ADK-TS-formatted messages
|
|
14041
14193
|
*/
|
|
14042
14194
|
setSamplingHandler(handler) {
|
|
14043
14195
|
if (!this.clientService) {
|
|
@@ -14071,7 +14223,7 @@ var McpToolset = class {
|
|
|
14071
14223
|
"resource_closed_error" /* RESOURCE_CLOSED_ERROR */
|
|
14072
14224
|
);
|
|
14073
14225
|
}
|
|
14074
|
-
if (this.tools.length > 0 &&
|
|
14226
|
+
if (this.tools.length > 0 && this.isCacheEnabled()) {
|
|
14075
14227
|
return this.tools;
|
|
14076
14228
|
}
|
|
14077
14229
|
if (!this.clientService) {
|
|
@@ -14100,7 +14252,7 @@ var McpToolset = class {
|
|
|
14100
14252
|
}
|
|
14101
14253
|
}
|
|
14102
14254
|
}
|
|
14103
|
-
if (this.
|
|
14255
|
+
if (this.isCacheEnabled()) {
|
|
14104
14256
|
this.tools = tools;
|
|
14105
14257
|
}
|
|
14106
14258
|
return tools;
|
|
@@ -14117,7 +14269,7 @@ var McpToolset = class {
|
|
|
14117
14269
|
}
|
|
14118
14270
|
}
|
|
14119
14271
|
/**
|
|
14120
|
-
* Converts ADK tools to MCP tool format for bidirectional support
|
|
14272
|
+
* Converts ADK-TS tools to MCP tool format for bidirectional support
|
|
14121
14273
|
*/
|
|
14122
14274
|
convertADKToolsToMCP(tools) {
|
|
14123
14275
|
return tools.map((tool) => adkToMcpToolType(tool));
|
|
@@ -14810,10 +14962,7 @@ var CodeExecutionUtils = class _CodeExecutionUtils {
|
|
|
14810
14962
|
* Gets the file content as a base64-encoded string
|
|
14811
14963
|
*/
|
|
14812
14964
|
static getEncodedFileContent(data) {
|
|
14813
|
-
|
|
14814
|
-
if (data instanceof ArrayBuffer) {
|
|
14815
|
-
decodedData = new TextDecoder().decode(data);
|
|
14816
|
-
}
|
|
14965
|
+
const decodedData = data instanceof ArrayBuffer ? new TextDecoder().decode(data) : data;
|
|
14817
14966
|
if (_CodeExecutionUtils.isBase64Encoded(decodedData)) {
|
|
14818
14967
|
return decodedData;
|
|
14819
14968
|
}
|
|
@@ -16776,7 +16925,7 @@ var BaseAgent = class {
|
|
|
16776
16925
|
}
|
|
16777
16926
|
/**
|
|
16778
16927
|
* The resolved beforeAgentCallback field as a list of SingleAgentCallback.
|
|
16779
|
-
* This method is only for use by
|
|
16928
|
+
* This method is only for use by ADK-TS.
|
|
16780
16929
|
*/
|
|
16781
16930
|
get canonicalBeforeAgentCallbacks() {
|
|
16782
16931
|
if (!this.beforeAgentCallback) {
|
|
@@ -16789,7 +16938,7 @@ var BaseAgent = class {
|
|
|
16789
16938
|
}
|
|
16790
16939
|
/**
|
|
16791
16940
|
* The resolved afterAgentCallback field as a list of SingleAgentCallback.
|
|
16792
|
-
* This method is only for use by
|
|
16941
|
+
* This method is only for use by ADK-TS.
|
|
16793
16942
|
*/
|
|
16794
16943
|
get canonicalAfterAgentCallbacks() {
|
|
16795
16944
|
if (!this.afterAgentCallback) {
|
|
@@ -17091,7 +17240,7 @@ var LlmAgent = class _LlmAgent extends BaseAgent {
|
|
|
17091
17240
|
}
|
|
17092
17241
|
/**
|
|
17093
17242
|
* The resolved model field as BaseLLM
|
|
17094
|
-
* This method is only for use by
|
|
17243
|
+
* This method is only for use by ADK-TS
|
|
17095
17244
|
*/
|
|
17096
17245
|
get canonicalModel() {
|
|
17097
17246
|
if (typeof this.model === "string") {
|
|
@@ -17116,7 +17265,7 @@ var LlmAgent = class _LlmAgent extends BaseAgent {
|
|
|
17116
17265
|
}
|
|
17117
17266
|
/**
|
|
17118
17267
|
* The resolved instruction field to construct instruction for this agent
|
|
17119
|
-
* This method is only for use by
|
|
17268
|
+
* This method is only for use by ADK-TS
|
|
17120
17269
|
*/
|
|
17121
17270
|
async canonicalInstruction(ctx) {
|
|
17122
17271
|
if (typeof this.instruction === "string") {
|
|
@@ -17127,7 +17276,7 @@ var LlmAgent = class _LlmAgent extends BaseAgent {
|
|
|
17127
17276
|
}
|
|
17128
17277
|
/**
|
|
17129
17278
|
* The resolved global_instruction field to construct global instruction
|
|
17130
|
-
* This method is only for use by
|
|
17279
|
+
* This method is only for use by ADK-TS
|
|
17131
17280
|
*/
|
|
17132
17281
|
async canonicalGlobalInstruction(ctx) {
|
|
17133
17282
|
if (typeof this.globalInstruction === "string") {
|
|
@@ -17138,7 +17287,7 @@ var LlmAgent = class _LlmAgent extends BaseAgent {
|
|
|
17138
17287
|
}
|
|
17139
17288
|
/**
|
|
17140
17289
|
* The resolved tools field as a list of BaseTool based on the context
|
|
17141
|
-
* This method is only for use by
|
|
17290
|
+
* This method is only for use by ADK-TS
|
|
17142
17291
|
*/
|
|
17143
17292
|
async canonicalTools(_ctx) {
|
|
17144
17293
|
const resolvedTools = [];
|
|
@@ -18543,6 +18692,7 @@ var LangGraphAgent = class extends BaseAgent {
|
|
|
18543
18692
|
* Core logic to run this agent via text-based conversation.
|
|
18544
18693
|
*/
|
|
18545
18694
|
async *runAsyncImpl(context4) {
|
|
18695
|
+
this.results = [];
|
|
18546
18696
|
this.logger.debug(
|
|
18547
18697
|
`Starting graph execution from root node "${this.rootNode}"`
|
|
18548
18698
|
);
|
|
@@ -18734,7 +18884,7 @@ function createBranchContextForSubAgent(agent, subAgent, invocationContext) {
|
|
|
18734
18884
|
agent: subAgent,
|
|
18735
18885
|
userContent: invocationContext.userContent,
|
|
18736
18886
|
session: invocationContext.session,
|
|
18737
|
-
|
|
18887
|
+
invocationFlags: invocationContext.getInvocationFlags(),
|
|
18738
18888
|
liveRequestQueue: invocationContext.liveRequestQueue,
|
|
18739
18889
|
activeStreamingTools: invocationContext.activeStreamingTools,
|
|
18740
18890
|
transcriptionCache: invocationContext.transcriptionCache,
|
|
@@ -19700,8 +19850,29 @@ var GcsArtifactService = class {
|
|
|
19700
19850
|
version
|
|
19701
19851
|
);
|
|
19702
19852
|
const blob = this.bucket.file(blobName);
|
|
19703
|
-
|
|
19704
|
-
|
|
19853
|
+
let data;
|
|
19854
|
+
let contentType;
|
|
19855
|
+
let partType;
|
|
19856
|
+
if (artifact.text !== void 0) {
|
|
19857
|
+
data = artifact.text;
|
|
19858
|
+
contentType = "text/plain";
|
|
19859
|
+
partType = "text";
|
|
19860
|
+
} else if (artifact.inlineData) {
|
|
19861
|
+
data = artifact.inlineData.data;
|
|
19862
|
+
contentType = artifact.inlineData.mimeType;
|
|
19863
|
+
partType = "inlineData";
|
|
19864
|
+
} else if (artifact.fileData) {
|
|
19865
|
+
data = artifact.fileData.fileUri;
|
|
19866
|
+
contentType = artifact.fileData.mimeType || "application/octet-stream";
|
|
19867
|
+
partType = "fileData";
|
|
19868
|
+
} else {
|
|
19869
|
+
throw new Error(
|
|
19870
|
+
"Unsupported artifact Part type: must have text, inlineData, or fileData"
|
|
19871
|
+
);
|
|
19872
|
+
}
|
|
19873
|
+
await blob.save(data, {
|
|
19874
|
+
contentType,
|
|
19875
|
+
metadata: { partType },
|
|
19705
19876
|
preconditionOpts: { ifGenerationMatch: 0 }
|
|
19706
19877
|
});
|
|
19707
19878
|
return version;
|
|
@@ -19735,12 +19906,25 @@ var GcsArtifactService = class {
|
|
|
19735
19906
|
if (!artifactBuffer) {
|
|
19736
19907
|
return null;
|
|
19737
19908
|
}
|
|
19738
|
-
const
|
|
19739
|
-
|
|
19740
|
-
|
|
19741
|
-
|
|
19742
|
-
|
|
19743
|
-
|
|
19909
|
+
const partType = metadata.metadata?.partType;
|
|
19910
|
+
let part;
|
|
19911
|
+
if (partType === "text") {
|
|
19912
|
+
part = { text: artifactBuffer.toString() };
|
|
19913
|
+
} else if (partType === "fileData") {
|
|
19914
|
+
part = {
|
|
19915
|
+
fileData: {
|
|
19916
|
+
fileUri: artifactBuffer.toString(),
|
|
19917
|
+
mimeType: metadata.contentType || "application/octet-stream"
|
|
19918
|
+
}
|
|
19919
|
+
};
|
|
19920
|
+
} else {
|
|
19921
|
+
part = {
|
|
19922
|
+
inlineData: {
|
|
19923
|
+
data: artifactBuffer.toString(),
|
|
19924
|
+
mimeType: metadata.contentType || "application/octet-stream"
|
|
19925
|
+
}
|
|
19926
|
+
};
|
|
19927
|
+
}
|
|
19744
19928
|
return part;
|
|
19745
19929
|
} catch (error) {
|
|
19746
19930
|
if (error?.code === 404) {
|
|
@@ -19864,7 +20048,7 @@ var EvalResult = class {
|
|
|
19864
20048
|
this.evalSetResultName = init.evalSetResultName;
|
|
19865
20049
|
this.evalSetId = init.evalSetId || "";
|
|
19866
20050
|
this.evalCaseResults = init.evalCaseResults || [];
|
|
19867
|
-
this.creationTimestamp = init.creationTimestamp || Date.now()
|
|
20051
|
+
this.creationTimestamp = init.creationTimestamp || Date.now();
|
|
19868
20052
|
}
|
|
19869
20053
|
};
|
|
19870
20054
|
|
|
@@ -19892,6 +20076,8 @@ var BaseEvalService = class {
|
|
|
19892
20076
|
};
|
|
19893
20077
|
|
|
19894
20078
|
// src/evaluation/vertex-ai-eval-facade.ts
|
|
20079
|
+
var import_google_auth_library = require("google-auth-library");
|
|
20080
|
+
var import_axios4 = __toESM(require("axios"));
|
|
19895
20081
|
var ERROR_MESSAGE_SUFFIX = `
|
|
19896
20082
|
You should specify both project id and location. This metric uses Vertex Gen AI
|
|
19897
20083
|
Eval SDK, and it requires google cloud credentials.
|
|
@@ -19902,6 +20088,28 @@ the template below:
|
|
|
19902
20088
|
process.env.GOOGLE_CLOUD_LOCATION = <LOCATION>
|
|
19903
20089
|
process.env.GOOGLE_CLOUD_PROJECT = <PROJECT ID>
|
|
19904
20090
|
`;
|
|
20091
|
+
var VERTEX_AI_EVAL_SCOPES = [
|
|
20092
|
+
"https://www.googleapis.com/auth/cloud-platform"
|
|
20093
|
+
];
|
|
20094
|
+
var VERTEX_AI_METRIC_KEYS = {
|
|
20095
|
+
["response_evaluation_score" /* RESPONSE_EVALUATION_SCORE */]: {
|
|
20096
|
+
inputKey: "coherence_input",
|
|
20097
|
+
resultKey: "coherenceResult"
|
|
20098
|
+
},
|
|
20099
|
+
["safety_v1" /* SAFETY_V1 */]: {
|
|
20100
|
+
inputKey: "safety_input",
|
|
20101
|
+
resultKey: "safetyResult"
|
|
20102
|
+
}
|
|
20103
|
+
};
|
|
20104
|
+
function getMetricKeys(metric) {
|
|
20105
|
+
const keys = VERTEX_AI_METRIC_KEYS[metric];
|
|
20106
|
+
if (!keys) {
|
|
20107
|
+
throw new Error(
|
|
20108
|
+
`Metric "${metric}" is not supported by Vertex AI evaluation.`
|
|
20109
|
+
);
|
|
20110
|
+
}
|
|
20111
|
+
return keys;
|
|
20112
|
+
}
|
|
19905
20113
|
var VertexAiEvalFacade = class _VertexAiEvalFacade {
|
|
19906
20114
|
threshold;
|
|
19907
20115
|
metricName;
|
|
@@ -19926,8 +20134,8 @@ var VertexAiEvalFacade = class _VertexAiEvalFacade {
|
|
|
19926
20134
|
};
|
|
19927
20135
|
try {
|
|
19928
20136
|
const evalCaseResult = await _VertexAiEvalFacade._performEval(
|
|
19929
|
-
|
|
19930
|
-
|
|
20137
|
+
evalCase,
|
|
20138
|
+
this.metricName
|
|
19931
20139
|
);
|
|
19932
20140
|
const score = this._getScore(evalCaseResult);
|
|
19933
20141
|
perInvocationResults.push({
|
|
@@ -19971,8 +20179,9 @@ var VertexAiEvalFacade = class _VertexAiEvalFacade {
|
|
|
19971
20179
|
return "";
|
|
19972
20180
|
}
|
|
19973
20181
|
_getScore(evalResult) {
|
|
19974
|
-
|
|
19975
|
-
|
|
20182
|
+
const meanScore = evalResult?.summaryMetrics?.[0]?.meanScore;
|
|
20183
|
+
if (typeof meanScore === "number" && !Number.isNaN(meanScore)) {
|
|
20184
|
+
return meanScore;
|
|
19976
20185
|
}
|
|
19977
20186
|
return void 0;
|
|
19978
20187
|
}
|
|
@@ -19982,7 +20191,7 @@ var VertexAiEvalFacade = class _VertexAiEvalFacade {
|
|
|
19982
20191
|
}
|
|
19983
20192
|
return 3 /* NOT_EVALUATED */;
|
|
19984
20193
|
}
|
|
19985
|
-
static async _performEval(
|
|
20194
|
+
static async _performEval(evalCase, metric) {
|
|
19986
20195
|
const projectId = process.env.GOOGLE_CLOUD_PROJECT;
|
|
19987
20196
|
const location = process.env.GOOGLE_CLOUD_LOCATION;
|
|
19988
20197
|
if (!projectId) {
|
|
@@ -19991,13 +20200,50 @@ var VertexAiEvalFacade = class _VertexAiEvalFacade {
|
|
|
19991
20200
|
if (!location) {
|
|
19992
20201
|
throw new Error(`Missing location. ${ERROR_MESSAGE_SUFFIX}`);
|
|
19993
20202
|
}
|
|
19994
|
-
|
|
19995
|
-
|
|
19996
|
-
)
|
|
20203
|
+
const auth = new import_google_auth_library.GoogleAuth({ scopes: VERTEX_AI_EVAL_SCOPES });
|
|
20204
|
+
const accessToken = await auth.getAccessToken();
|
|
20205
|
+
if (!accessToken) {
|
|
20206
|
+
throw new Error(
|
|
20207
|
+
"Failed to obtain Google Cloud access token. Ensure Application Default Credentials are configured (e.g. run 'gcloud auth application-default login')."
|
|
20208
|
+
);
|
|
20209
|
+
}
|
|
20210
|
+
const { inputKey, resultKey } = getMetricKeys(metric);
|
|
20211
|
+
const url = `https://${location}-aiplatform.googleapis.com/v1beta1/projects/${projectId}/locations/${location}:evaluateInstances`;
|
|
20212
|
+
const instance = {
|
|
20213
|
+
prediction: evalCase.response
|
|
20214
|
+
};
|
|
20215
|
+
if (metric === "response_evaluation_score" /* RESPONSE_EVALUATION_SCORE */) {
|
|
20216
|
+
instance.reference = evalCase.reference;
|
|
20217
|
+
}
|
|
20218
|
+
const requestBody = {
|
|
20219
|
+
[inputKey]: {
|
|
20220
|
+
metric_spec: {},
|
|
20221
|
+
instance
|
|
20222
|
+
}
|
|
20223
|
+
};
|
|
20224
|
+
let responseData;
|
|
20225
|
+
try {
|
|
20226
|
+
const response = await import_axios4.default.post(url, requestBody, {
|
|
20227
|
+
headers: {
|
|
20228
|
+
Authorization: `Bearer ${accessToken}`,
|
|
20229
|
+
"Content-Type": "application/json"
|
|
20230
|
+
}
|
|
20231
|
+
});
|
|
20232
|
+
responseData = response.data;
|
|
20233
|
+
} catch (error) {
|
|
20234
|
+
if (import_axios4.default.isAxiosError(error)) {
|
|
20235
|
+
const detail = error.response?.data ? JSON.stringify(error.response.data) : "";
|
|
20236
|
+
throw new Error(
|
|
20237
|
+
`Vertex AI evaluation API request failed: ${error.message}${detail ? ` \u2014 ${detail}` : ""}`
|
|
20238
|
+
);
|
|
20239
|
+
}
|
|
20240
|
+
throw error;
|
|
20241
|
+
}
|
|
20242
|
+
const score = responseData?.[resultKey]?.score;
|
|
19997
20243
|
return {
|
|
19998
20244
|
summaryMetrics: [
|
|
19999
20245
|
{
|
|
20000
|
-
meanScore:
|
|
20246
|
+
meanScore: typeof score === "number" ? score : void 0
|
|
20001
20247
|
}
|
|
20002
20248
|
]
|
|
20003
20249
|
};
|
|
@@ -20453,9 +20699,13 @@ var LocalEvalService = class extends BaseEvalService {
|
|
|
20453
20699
|
super();
|
|
20454
20700
|
this.agent = agent;
|
|
20455
20701
|
this.parallelism = parallelism;
|
|
20456
|
-
this.initializeRunner();
|
|
20702
|
+
this.readyPromise = this.initializeRunner();
|
|
20457
20703
|
}
|
|
20458
20704
|
runner;
|
|
20705
|
+
readyPromise;
|
|
20706
|
+
ensureReady() {
|
|
20707
|
+
return this.readyPromise;
|
|
20708
|
+
}
|
|
20459
20709
|
async initializeRunner() {
|
|
20460
20710
|
if ("ask" in this.agent) {
|
|
20461
20711
|
this.runner = this.agent;
|
|
@@ -20554,9 +20804,7 @@ var LocalEvalService = class extends BaseEvalService {
|
|
|
20554
20804
|
}
|
|
20555
20805
|
async runInference(evalCase) {
|
|
20556
20806
|
const results = [];
|
|
20557
|
-
|
|
20558
|
-
await this.initializeRunner();
|
|
20559
|
-
}
|
|
20807
|
+
await this.ensureReady();
|
|
20560
20808
|
if (evalCase.sessionInput) {
|
|
20561
20809
|
try {
|
|
20562
20810
|
if (this.runner.initializeSession) {
|
|
@@ -23114,6 +23362,7 @@ var import_kysely = require("kysely");
|
|
|
23114
23362
|
var DatabaseSessionService = class extends BaseSessionService {
|
|
23115
23363
|
db;
|
|
23116
23364
|
initialized = false;
|
|
23365
|
+
initPromise = null;
|
|
23117
23366
|
constructor(config) {
|
|
23118
23367
|
super();
|
|
23119
23368
|
this.db = config.db;
|
|
@@ -23124,12 +23373,26 @@ var DatabaseSessionService = class extends BaseSessionService {
|
|
|
23124
23373
|
}
|
|
23125
23374
|
}
|
|
23126
23375
|
/**
|
|
23127
|
-
* Initialize the database by creating required tables if they don't exist
|
|
23376
|
+
* Initialize the database by creating required tables if they don't exist.
|
|
23377
|
+
* Uses promise deduplication so concurrent callers share a single initialization.
|
|
23128
23378
|
*/
|
|
23129
|
-
|
|
23379
|
+
initializeDatabase() {
|
|
23130
23380
|
if (this.initialized) {
|
|
23131
|
-
return;
|
|
23381
|
+
return Promise.resolve();
|
|
23382
|
+
}
|
|
23383
|
+
if (this.initPromise) {
|
|
23384
|
+
return this.initPromise;
|
|
23132
23385
|
}
|
|
23386
|
+
const promise = this._doInitialize();
|
|
23387
|
+
this.initPromise = promise;
|
|
23388
|
+
promise.catch(() => {
|
|
23389
|
+
if (this.initPromise === promise) {
|
|
23390
|
+
this.initPromise = null;
|
|
23391
|
+
}
|
|
23392
|
+
});
|
|
23393
|
+
return promise;
|
|
23394
|
+
}
|
|
23395
|
+
async _doInitialize() {
|
|
23133
23396
|
try {
|
|
23134
23397
|
await this.db.schema.createTable("sessions").ifNotExists().addColumn("id", "varchar(128)", (col) => col.notNull()).addColumn("app_name", "varchar(128)", (col) => col.notNull()).addColumn("user_id", "varchar(128)", (col) => col.notNull()).addColumn("state", "text", (col) => col.defaultTo("{}")).addColumn(
|
|
23135
23398
|
"create_time",
|
|
@@ -23396,7 +23659,8 @@ var DatabaseSessionService = class extends BaseSessionService {
|
|
|
23396
23659
|
session.lastUpdateTime = this.timestampToUnixSeconds(
|
|
23397
23660
|
updatedSession.update_time
|
|
23398
23661
|
);
|
|
23399
|
-
|
|
23662
|
+
this.updateSessionState(session, event);
|
|
23663
|
+
session.events.push(event);
|
|
23400
23664
|
return event;
|
|
23401
23665
|
});
|
|
23402
23666
|
}
|