@waldzellai/adk-typescript
Version:
TypeScript SDK for Google Agent Development Kit (ADK) - A comprehensive framework for building AI agents
220 lines (219 loc) • 8.86 kB
JavaScript
;
// CLI implementation for the Google Agent Development Kit (ADK) in TypeScript
// Mirrors the CLI functionality from the Python SDK
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.runInputFile = runInputFile;
exports.runInteractively = runInteractively;
exports.runCli = runCli;
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const artifacts_1 = require("../artifacts");
const runners_1 = require("../runners");
const sessions_1 = require("../sessions");
const envs_1 = require("./utils/envs");
const readline = __importStar(require("readline"));
/**
* Runs an agent with queries from an input file
*
* @param appName The application name
* @param rootAgent The root agent to run
* @param artifactService The artifact service to use
* @param session The session to use
* @param sessionService The session service to use
* @param inputPath The path to the input file
*/
async function runInputFile(appName, rootAgent, artifactService, session, sessionService, inputPath) {
const runner = new runners_1.Runner({
appName,
agent: rootAgent,
artifactService,
sessionService
});
const inputFileContent = fs.readFileSync(inputPath, 'utf-8');
const inputFile = JSON.parse(inputFileContent);
inputFile.state['_time'] = new Date();
session.state = inputFile.state;
for (const query of inputFile.queries) {
console.log(`user: ${query}`);
const content = {
role: 'user',
parts: [{ text: query }]
};
for await (const event of runner.runAsync({ userId: session.userId, sessionId: session.id, newMessage: content })) {
if (event.getContent()) {
const parts = event.getContent()?.parts || [];
const text = parts
.filter(part => part.text)
.map(part => part.text)
.join('');
if (text) {
console.log(`[${event.getAuthor()}]: ${text}`);
}
}
}
}
}
/**
* Runs an agent interactively
*
* @param appName The application name
* @param rootAgent The root agent to run
* @param artifactService The artifact service to use
* @param session The session to use
* @param sessionService The session service to use
*/
async function runInteractively(appName, rootAgent, artifactService, session, sessionService) {
const runner = new runners_1.Runner({
appName,
agent: rootAgent,
artifactService,
sessionService
});
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
const promptUser = () => {
return new Promise((resolve) => {
rl.question('user: ', (answer) => {
resolve(answer);
});
});
};
while (true) {
const query = await promptUser();
if (query === 'exit') {
break;
}
const content = {
role: 'user',
parts: [{ text: query }]
};
for await (const event of runner.runAsync({ userId: session.userId, sessionId: session.id, newMessage: content })) {
if (event.getContent()) {
const parts = event.getContent()?.parts || [];
const text = parts
.filter(part => part.text)
.map(part => part.text)
.join('');
if (text) {
console.log(`[${event.getAuthor()}]: ${text}`);
}
}
}
}
rl.close();
}
/**
* Runs the CLI with the given options
*
* @param options The options for running the CLI
*/
async function runCli(options) {
const { agentParentDir, agentFolderName, jsonFilePath, saveSession } = options;
// Add the agent parent directory to the module search path if needed
// This is a Node.js-specific implementation for handling module imports
const artifactService = new artifacts_1.InMemoryArtifactService();
const sessionService = new sessions_1.InMemorySessionService();
const session = sessionService.createSession(agentFolderName, 'test_user');
try {
// This is a simplistic approach - in a real implementation,
// we would need more sophisticated module loading and integration
const agentModulePath = path.join(agentParentDir, agentFolderName);
// In TypeScript we'd use a dynamic import approach instead of importlib
const agentModule = await Promise.resolve(`${agentModulePath}`).then(s => __importStar(require(s)));
const rootAgent = agentModule.agent.rootAgent;
// Load environment variables for the agent
(0, envs_1.loadDotEnvForAgent)(agentFolderName, agentParentDir);
if (jsonFilePath) {
if (jsonFilePath.endsWith('.input.json')) {
await runInputFile(agentFolderName, rootAgent, artifactService, session, sessionService, jsonFilePath);
}
else if (jsonFilePath.endsWith('.session.json')) {
const sessionFileContent = fs.readFileSync(jsonFilePath, 'utf-8');
const sessionData = JSON.parse(sessionFileContent);
const loadedSession = new sessions_1.Session(sessionData);
for (const content of loadedSession.getContents()) {
if (content.role === 'user') {
console.log('user: ', content.parts?.[0]?.text);
}
else {
console.log(content.parts?.[0]?.text);
}
}
await runInteractively(agentFolderName, rootAgent, artifactService, loadedSession, sessionService);
}
else {
console.log(`Unsupported file type: ${jsonFilePath}`);
process.exit(1);
}
}
else {
console.log(`Running agent ${rootAgent.name}, type exit to exit.`);
await runInteractively(agentFolderName, rootAgent, artifactService, session, sessionService);
}
if (saveSession) {
let sessionPath;
if (jsonFilePath) {
sessionPath = jsonFilePath.replace('.input.json', '.session.json');
}
else {
// In Node.js, we'd use a different approach for getting user input
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
const sessionId = await new Promise((resolve) => {
rl.question('Session ID to save: ', (answer) => {
resolve(answer);
rl.close();
});
});
sessionPath = path.join(agentModulePath, `${sessionId}.session.json`);
}
// Fetch the session again to get all the details
const updatedSession = sessionService.getSession(session.appName, session.userId, session.id);
if (updatedSession) {
fs.writeFileSync(sessionPath, JSON.stringify(updatedSession, null, 2));
console.log('Session saved to', sessionPath);
}
}
}
catch (error) {
console.error('Error running CLI:', error);
process.exit(1);
}
}