UNPKG

@salesforce/agents

Version:

Client side APIs for working with Salesforce agents

169 lines 7.13 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.AgentBase = void 0; /* * Copyright 2026, Salesforce, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ const promises_1 = require("node:fs/promises"); const node_path_1 = require("node:path"); const core_1 = require("@salesforce/core"); const utils_1 = require("../utils"); const connectionManager_1 = require("../connectionManager"); /** * Abstract base class for agent preview functionality. * Contains shared properties and methods between ScriptAgent and ProductionAgent. */ class AgentBase { /** * The display name of the agent (user-friendly name, not API name) */ name; /** * The Connection passed in by the caller. Used as the lookup key into the ConnectionManager * cache (see managerFor()) — never used directly for SFAP or org API calls. Subclasses go * through getJwtConnection() / getStandardConnection() so that JWT and standard connections * remain isolated. */ connection; sessionId; historyDir; historyBuffer; turnCounter = 0; apexDebugging; planIds = new Set(); constructor(connection) { this.connection = connection; } /** * Refreshes the access token on the standard connection. * * Retained for backward compatibility. The caller's original Connection is never mutated * by agent operations, so this only refreshes the internal standard connection owned by * the ConnectionManager. */ async restoreConnection() { const manager = await (0, connectionManager_1.managerFor)(this.connection); await manager.refreshStandardConnection(); } setSessionId(sessionId) { this.sessionId = sessionId; } async getHistoryDir() { if (!this.sessionId) { throw core_1.SfError.create({ message: 'No sessionId set on agent. Call setSessionId() before getHistoryDir().' }); } return (0, utils_1.getHistoryDir)(await this.getAgentIdForStorage(), this.sessionId); } /** * Resume an existing session by loading session state from disk * * @param sessionId The session ID to resume */ async resumeSession(sessionId) { this.sessionId = sessionId; const agentId = await this.getAgentIdForStorage(); this.historyDir = await (0, utils_1.getHistoryDir)(agentId, sessionId); // Load session data from disk const { buffer, turnCount } = await utils_1.SessionHistoryBuffer.fromDisk(this.historyDir, sessionId, agentId); this.historyBuffer = buffer; this.turnCounter = turnCount; // Load planIds from buffer const history = await this.getHistoryFromDisc(); if (history.metadata?.planIds) { history.metadata.planIds.forEach((planId) => this.planIds.add(planId)); } } /** * Returns the connection to use for SFAP API calls (api.salesforce.com/einstein/ai-agent). * Always the JWT-upgraded connection from the ConnectionManager — never the caller's * original Connection. */ async getJwtConnection() { const manager = await (0, connectionManager_1.managerFor)(this.connection); return manager.getJwtConnection(); } /** * Returns the standard org connection for SOQL queries, tooling API, and metadata * operations. Always the manager's isolated standard connection — never the caller's * original Connection — to keep JWT and org auth fully separate. */ async getStandardConnection() { const manager = await (0, connectionManager_1.managerFor)(this.connection); return manager.getStandardConnection(); } /** * Get all traces from the current session * Reads traces from the session directory if available, otherwise fetches from API */ async getAllTracesFromDisc() { if (!this.historyDir) { throw core_1.SfError.create({ message: 'history never created' }); } const traces = []; // If we have a session directory, try reading traces from disk first const tracesDir = (0, node_path_1.join)(this.historyDir, 'traces'); const files = await (0, promises_1.readdir)(tracesDir); const tracePromises = files .filter((file) => file.endsWith('.json')) .map(async (file) => { const traceData = await (0, promises_1.readFile)((0, node_path_1.join)(tracesDir, file), 'utf-8'); return JSON.parse(traceData); }); traces.push(...(await Promise.all(tracePromises))); return traces; } /** * Save the complete session data to disk by copying the session directory. * The session directory is already populated during the session with: * - Transcript entries (transcript.jsonl) * - Traces (traces/*.json) * - Session metadata (metadata.json) * * Session directory structure: * .sfdx/agents/<agentId>/sessions/<sessionId>/ * ├── transcript.jsonl # All transcript entries (one per line) * ├── traces/ # Individual trace files * │ ├── <planId1>.json * │ └── <planId2>.json * └── metadata.json # Session metadata (start time, end time, planIds, etc.) * * @param outputDir Optional output directory. If not provided, uses default location. * @returns The path to the copied session directory */ async saveSessionTo(outputDir) { if (!this.sessionId || !this.historyDir) { throw core_1.SfError.create({ name: 'noSessionId', message: 'No active session. Call .start() first.' }); } const agentId = await this.getAgentIdForStorage(); // Determine output directory const destDir = (0, node_path_1.join)(outputDir, agentId, `session_${this.sessionId}`); // Copy the entire session directory from .sfdx to the output directory // This includes transcript.jsonl, traces/, and metadata.json await (0, promises_1.mkdir)(destDir, { recursive: true }); await (0, promises_1.cp)(this.historyDir, destDir, { recursive: true }); return destDir; } /** * Set the Apex debugging mode for the agent preview. * This can be called before starting a session. * * @param apexDebugging true to enable Apex debugging, false to disable */ setApexDebugging(apexDebugging) { this.apexDebugging = apexDebugging; } } exports.AgentBase = AgentBase; //# sourceMappingURL=agentBase.js.map