adk-typescript
Version:
TypeScript port of Google's Agent Development Kit (ADK)
170 lines (157 loc) • 6.28 kB
JavaScript
;
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.toCloudRun = toCloudRun;
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const child_process = __importStar(require("child_process"));
const DOCKERFILE_TEMPLATE = `
FROM python:3.11-slim
WORKDIR /app
# Create a non-root user
RUN adduser --disabled-password --gecos "" myuser
# Change ownership of /app to myuser
RUN chown -R myuser:myuser /app
# Switch to the non-root user
USER myuser
# Set up environment variables - Start
ENV PATH="/home/myuser/.local/bin:$PATH"
ENV GOOGLE_GENAI_USE_VERTEXAI=1
ENV GOOGLE_CLOUD_PROJECT={gcp_project_id}
ENV GOOGLE_CLOUD_LOCATION={gcp_region}
# Set up environment variables - End
# Install ADK - Start
RUN pip install google-adk
# Install ADK - End
# Copy agent - Start
COPY "agents/{app_name}/" "/app/agents/{app_name}/"
{install_agent_deps}
# Copy agent - End
EXPOSE {port}
CMD adk {command} --port={port} {session_db_option} {trace_to_cloud_option} "/app/agents"
`;
async function resolveProject(projectInOption) {
if (projectInOption)
return projectInOption;
try {
const result = child_process.spawnSync('gcloud', ['config', 'get-value', 'project'], {
encoding: 'utf-8',
});
if (result.status === 0 && result.stdout) {
const project = result.stdout.trim();
console.log(`Use default project: ${project}`);
return project;
}
}
catch (e) {
console.log('Error getting default project:', e);
}
throw new Error('Could not resolve Google Cloud project.');
}
async function toCloudRun({ agentFolder, project, region, serviceName, appName, tempFolder, port, traceToCloud, withUi, verbosity, sessionDbUrl, }) {
appName = appName || path.basename(agentFolder);
console.log(`Start generating Cloud Run source files in ${tempFolder}`);
// Remove tempFolder if exists
if (fs.existsSync(tempFolder)) {
console.log('Removing existing files');
fs.rmSync(tempFolder, { recursive: true, force: true });
}
try {
// Copy agent source code
console.log('Copying agent source code...');
const agentSrcPath = path.join(tempFolder, 'agents', appName);
fs.mkdirSync(path.dirname(agentSrcPath), { recursive: true });
copyDir(agentFolder, agentSrcPath);
const requirementsTxtPath = path.join(agentSrcPath, 'requirements.txt');
const installAgentDeps = fs.existsSync(requirementsTxtPath)
? `RUN pip install -r "/app/agents/${appName}/requirements.txt"`
: '';
console.log('Copying agent source code complete.');
// Create Dockerfile
console.log('Creating Dockerfile...');
const dockerfileContent = DOCKERFILE_TEMPLATE
.replace(/{gcp_project_id}/g, project || '')
.replace(/{gcp_region}/g, region || '')
.replace(/{app_name}/g, appName)
.replace(/{port}/g, String(port))
.replace(/{command}/g, withUi ? 'web' : 'api_server')
.replace(/{install_agent_deps}/g, installAgentDeps)
.replace(/{session_db_option}/g, sessionDbUrl ? `--db_url=${sessionDbUrl}` : '')
.replace(/{trace_to_cloud_option}/g, traceToCloud ? '--trace_to_cloud' : '');
const dockerfilePath = path.join(tempFolder, 'Dockerfile');
fs.mkdirSync(tempFolder, { recursive: true });
await fs.promises.writeFile(dockerfilePath, dockerfileContent, 'utf-8');
console.log(`Creating Dockerfile complete: ${dockerfilePath}`);
// Deploy to Cloud Run
console.log('Deploying to Cloud Run...');
const regionOptions = region ? ['--region', region] : [];
const resolvedProject = await resolveProject(project);
child_process.execFileSync('gcloud', [
'run',
'deploy',
serviceName,
'--source',
tempFolder,
'--project',
resolvedProject,
...regionOptions,
'--port',
String(port),
'--verbosity',
verbosity,
'--labels',
'created-by=adk',
], { stdio: 'inherit' });
}
finally {
console.log(`Cleaning up the temp folder: ${tempFolder}`);
fs.rmSync(tempFolder, { recursive: true, force: true });
}
}
function copyDir(src, dest) {
if (!fs.existsSync(dest)) {
fs.mkdirSync(dest, { recursive: true });
}
for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
const srcPath = path.join(src, entry.name);
const destPath = path.join(dest, entry.name);
if (entry.isDirectory()) {
copyDir(srcPath, destPath);
}
else {
fs.copyFileSync(srcPath, destPath);
}
}
}