Feat: Replace Promise<void> with proper Task type in ActiveStreamingTool Staging#468
Feat: Replace Promise<void> with proper Task type in ActiveStreamingTool Staging#468AmaadMartin wants to merge 1 commit into
Conversation
kalenkevich
left a comment
There was a problem hiding this comment.
What is the purpose of that Task object?
The main purpose is to get parity with ADK Python. A Promise object can't be cancelled once created, and also doesn't allow for synchronous status checks. Both of these are supported by the asyncio.Task type which ADK Python uses. The Task object in this PR supports both of those usecases for parity. |
Can you please show an example of the real usage? |
7644c40 to
9b215ba
Compare
Example 1: A Tool that Runs Forever (Continuous Monitoring)Scenario: A tool that streams real-time data continuously, such as monitoring stock prices, CPU usage, or a live camera feed. It uses an infinite loop to poll for updates. // TS representation of a tool that runs forever
async function* monitorStockPrice(symbol: string) {
yield `Started monitoring ${symbol}`;
while (true) { // Infinite loop: Will never exit on its own
const price = await fetchPrice(symbol);
yield `Price update for ${symbol}: $${price}`;
await sleep(5000); // Polls every 5 seconds
}
}
Example 2: A Tool that Doesn't Run Forever, but Needs to be Stopped (Long-Running Task)Scenario: A tool that performs a heavy computation, downloads a large file, or runs a complex database query. It will eventually finish, but it takes a significant amount of time (e.g., several minutes). // TS representation of a long-running tool that eventually finishes
async function* downloadLargeFile(url: string, destination: string, abortSignal: AbortSignal) {
const response = await fetch(url, { signal: abortSignal });
const reader = response.body.getReader();
while (true) {
const { done, value } = await reader.read();
if (done) break;
await writeToDisk(destination, value);
yield `Download progress: ${value.length} bytes written`;
if (abortSignal.aborted) {
throw new Error("Download cancelled");
}
}
}
|
9b215ba to
20122f8
Compare
Please ensure you have read the contribution guide before creating a pull request.
Link to Issue or Description of Change
1. Link to an existing issue (if applicable):
2. Or, if no issue exists, describe the change:
Problem:
ActiveStreamingTool.taskwas typed asPromise<void>, which didn't allow for runtime control (cancellation, status check) like the Python reference implementation which usesasyncio.Task.Solution:
Implemented a concrete
Taskclass incore/src/utils/task.tsthat wraps a promise and supportscancel()anddone(). UpdatedActiveStreamingToolto use thisTasktype. Updated exports incommon.tsandindex.ts.Testing Plan
Please describe the tests that you ran to verify your changes. This is required
for all PRs that are not small documentation or typo fixes.
Unit Tests:
Passed vitest results for:
core/test/utils/task_test.tscore/test/agents/active_streaming_tool_test.tsManual End-to-End (E2E) Tests:
Updated
tests/e2e/streaming/task_e2e_test.tsto simulate a streaming tool task using the newTaskclass andLiveRequestQueue, and verified it runs and passes.Checklist
Additional context
None.