UNPKG

@openai/agents-core

Version:

The OpenAI Agents SDK is a lightweight yet powerful framework for building multi-agent workflows.

431 lines • 17.2 kB
"use strict"; 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.SandboxMemoryGenerationManager = void 0; exports.getOrCreateSandboxMemoryGenerationManager = getOrCreateSandboxMemoryGenerationManager; const _shims_1 = require("@openai/agents-core/_shims"); const zod_1 = require("zod"); const errors_1 = require("../../errors.js"); const logger_1 = __importStar(require("../../logger.js")); const manifest_1 = require("../manifest.js"); const sessionLifecycle_1 = require("../runtime/sessionLifecycle.js"); const spans_1 = require("../runtime/spans.js"); const stableJson_1 = require("../shared/stableJson.js"); const rollouts_1 = require("./rollouts.js"); const storage_1 = require("./storage.js"); const prompts_1 = require("./prompts.js"); const RolloutExtractionArtifactsSchema = zod_1.z.object({ rollout_summary: zod_1.z.string(), rollout_slug: zod_1.z.string(), raw_memory: zod_1.z.string(), }); const managersBySession = new WeakMap(); const objectIds = new WeakMap(); let nextObjectId = 1; function getOrCreateSandboxMemoryGenerationManager(args) { if (args.memory.generate === null) { throw new errors_1.UserError('SandboxMemoryGenerationManager requires Memory.generate to be enabled.'); } const layout = normalizedLayout(args.memory); const layoutKey = memoryLayoutKey(args.memory); let registry = managersBySession.get(args.session); const existing = registry?.get(layoutKey); if (existing) { const nextSignature = memoryGenerationSignature(args.memory.generate); if (existing.generationSignature !== nextSignature) { throw new errors_1.UserError('Sandbox session already has a different Memory generation config attached for this memory layout.'); } if (existing.manager.isStopped()) { registry.delete(layoutKey); if (registry.size === 0) { managersBySession.delete(args.session); registry = undefined; } } else { existing.manager.updateRuntimeContext({ runAs: args.runAs, runAgent: args.runAgent, tracingParent: args.tracingParent, }); return existing.manager; } } if (registry) { for (const entry of registry.values()) { if (entry.layout.memoriesDir === layout.memoriesDir) { throw new errors_1.UserError(`Sandbox session already has a Memory generation capability for memoriesDir=${layout.memoriesDir}. Use a different memoriesDir for isolated memories, or the same layout to share memory.`); } if (entry.layout.sessionsDir === layout.sessionsDir) { throw new errors_1.UserError(`Sandbox session already has a Memory generation capability for sessionsDir=${layout.sessionsDir}. Use a different sessionsDir for isolated memories, or the same layout to share memory.`); } } } const manager = new SandboxMemoryGenerationManager(args); registry ??= new Map(); registry.set(layoutKey, { memory: args.memory, manager, generationSignature: memoryGenerationSignature(args.memory.generate), layout, }); managersBySession.set(args.session, registry); return manager; } class SandboxMemoryGenerationManager { session; memory; runAs; runAgent; tracingParent; storage; pendingRolloutIds = new Set(); flushPromise; stopped = false; unregisterPreStopHook; constructor(args) { this.session = args.session; this.memory = args.memory; this.runAs = args.runAs; this.runAgent = args.runAgent; this.tracingParent = args.tracingParent; this.storage = new storage_1.SandboxMemoryStorage({ session: args.session, runAs: args.runAs, store: args.memory.store, tracingParent: args.tracingParent, }); this.unregisterPreStopHook = (0, sessionLifecycle_1.registerSandboxPreStopHook)(this.session, async () => { await this.flush(); }); } isStopped() { return this.stopped; } updateRuntimeContext(args) { this.runAs = args.runAs; this.runAgent = args.runAgent; this.tracingParent = args.tracingParent; this.storage.updateRuntimeContext({ runAs: args.runAs, tracingParent: args.tracingParent, }); } async enqueueState(state, args) { if (this.memory.generate === null || this.stopped) { return; } const rolloutId = (0, rollouts_1.resolveMemoryRolloutId)({ ...args.rolloutIdentity, fallbackId: (0, _shims_1.randomUUID)(), }); const payload = (0, rollouts_1.buildMemoryRolloutPayload)(state, { rolloutId, exception: args.exception, inputOverride: args.inputOverride, }); await (0, spans_1.withSandboxSpan)('sandbox.memory.enqueue_rollout', { rollout_id: rolloutId, }, async () => { await this.storage.ensureLayout(this.memory); await this.storage.appendJsonl((0, storage_1.joinRelativePaths)(this.memory.layout.sessionsDir, `${rolloutId}.jsonl`), payload); this.pendingRolloutIds.add(rolloutId); }, this.tracingParent); } async flush() { if (this.flushPromise) { await this.flushPromise; return; } this.flushPromise = this.flushOnce(); try { await this.flushPromise; } finally { this.flushPromise = undefined; } } async flushOnce() { if (this.memory.generate === null) { return; } if (this.stopped) { this.unregister(); return; } this.stopped = true; try { await (0, spans_1.withSandboxSpan)('sandbox.memory.flush', { rollout_count: this.pendingRolloutIds.size, }, async () => { await this.storage.ensureLayout(this.memory); let wroteArtifacts = false; for (const rolloutId of [...this.pendingRolloutIds].sort()) { try { const extraction = await this.runPhaseOne(rolloutId); if (!validateRolloutArtifacts(extraction)) { continue; } await this.persistPhaseOneArtifacts(rolloutId, extraction); wroteArtifacts = true; } catch (error) { (0, logger_1.logModelAndToolActionWarning)(logger_1.default, 'Sandbox memory phase 1 failed:', error, { rolloutId }); } } if (wroteArtifacts) { try { await this.runPhaseTwo(); } catch (error) { (0, logger_1.logModelAndToolActionWarning)(logger_1.default, 'Sandbox memory phase 2 failed:', error); } } }, this.tracingParent); } finally { this.pendingRolloutIds.clear(); this.unregister(); } } async runPhaseOne(rolloutId) { const generate = this.memory.generate; if (generate === null) { throw new errors_1.UserError('Memory generation is disabled.'); } const transcriptPath = (0, storage_1.joinRelativePaths)(this.memory.layout.sessionsDir, `${rolloutId}.jsonl`); const transcript = await this.storage.readText(transcriptPath); if (!transcript) { throw new errors_1.UserError(`Memory rollout transcript was not found: ${transcriptPath}`); } const { SandboxAgent } = await Promise.resolve().then(() => __importStar(require("../agent.js"))); const phaseOneAgent = new SandboxAgent({ name: 'sandbox-memory-phase-one', instructions: (0, prompts_1.renderRolloutExtractionInstructions)(generate.extraPrompt), model: generate.phaseOneModel, modelSettings: generate.phaseOneModelSettings, outputType: RolloutExtractionArtifactsSchema, defaultManifest: this.currentManifest(), runAs: this.runAs, }); const result = await this.runAgent(phaseOneAgent, (0, prompts_1.renderRolloutExtractionUserPrompt)({ terminalMetadataJson: (0, rollouts_1.renderPhaseOnePrompt)(transcript), rolloutContents: transcript, }), { sandbox: { session: this.session, manifest: this.currentManifest(), }, maxTurns: 500, }); return RolloutExtractionArtifactsSchema.parse(result.finalOutput); } async persistPhaseOneArtifacts(rolloutId, extraction) { const memoriesDir = this.memory.layout.memoriesDir; const transcriptPath = (0, storage_1.joinRelativePaths)(this.memory.layout.sessionsDir, `${rolloutId}.jsonl`); const transcript = await this.storage.readText(transcriptPath); const metadata = rolloutMetadataFromTranscript(transcript ?? ''); const slug = (0, rollouts_1.normalizeRolloutSlug)(extraction.rollout_slug); const rolloutPath = (0, storage_1.joinRelativePaths)(this.memory.layout.sessionsDir, `${rolloutId}.jsonl`); const rolloutSummaryFile = (0, storage_1.joinRelativePaths)('rollout_summaries', `${rolloutId}_${slug}.md`); await this.storage.writeText((0, storage_1.joinRelativePaths)(memoriesDir, 'raw_memories', `${rolloutId}.md`), formatRawMemory({ updatedAt: metadata.updatedAt, rolloutId, rolloutPath, rolloutSummaryFile, terminalState: metadata.terminalState, rawMemory: extraction.raw_memory, })); await this.storage.writeText((0, storage_1.joinRelativePaths)(memoriesDir, rolloutSummaryFile), formatRolloutSummary({ updatedAt: metadata.updatedAt, rolloutPath, sessionId: String(this.session.state.sessionId ?? ''), terminalState: metadata.terminalState, rolloutSummary: extraction.rollout_summary, })); } async runPhaseTwo() { const generate = this.memory.generate; if (generate === null) { throw new errors_1.UserError('Memory generation is disabled.'); } const selection = await this.storage.buildPhaseTwoInputSelection({ memoriesDir: this.memory.layout.memoriesDir, maxRawMemoriesForConsolidation: generate.maxRawMemoriesForConsolidation ?? 256, }); if (!(await this.storage.rebuildRawMemories({ memoriesDir: this.memory.layout.memoriesDir, selectedItems: selection.selected, }))) { return; } const { SandboxAgent } = await Promise.resolve().then(() => __importStar(require("../agent.js"))); const phaseTwoAgent = new SandboxAgent({ name: 'sandbox-memory-phase-two', model: generate.phaseTwoModel, modelSettings: generate.phaseTwoModelSettings, defaultManifest: this.currentManifest(), runAs: this.runAs, }); await this.runAgent(phaseTwoAgent, (0, prompts_1.renderMemoryConsolidationPrompt)({ memoryRoot: this.memory.layout.memoriesDir, selection, extraPrompt: generate.extraPrompt, }), { sandbox: { session: this.session, manifest: this.currentManifest(), }, maxTurns: generate.phaseTwoMaxTurns ?? 500, }); await this.storage.writePhaseTwoSelection({ memoriesDir: this.memory.layout.memoriesDir, selectedItems: selection.selected, }); } currentManifest() { return new manifest_1.Manifest(this.session.state.manifest); } unregister() { this.unregisterPreStopHook?.(); this.unregisterPreStopHook = undefined; const registry = managersBySession.get(this.session); if (!registry) { return; } const layoutKey = memoryLayoutKey(this.memory); const existing = registry.get(layoutKey); if (existing?.manager === this) { registry.delete(layoutKey); } if (registry.size === 0) { managersBySession.delete(this.session); } } } exports.SandboxMemoryGenerationManager = SandboxMemoryGenerationManager; function validateRolloutArtifacts(artifacts) { const hasSlug = artifacts.rollout_slug.trim().length > 0; const hasSummary = artifacts.rollout_summary.trim().length > 0; const hasRawMemory = artifacts.raw_memory.trim().length > 0; if (!hasSlug && !hasSummary && !hasRawMemory) { return false; } if (!hasSlug || !hasSummary || !hasRawMemory) { throw new errors_1.UserError('Phase 1 returned partially-empty memory artifacts.'); } (0, rollouts_1.normalizeRolloutSlug)(artifacts.rollout_slug); return true; } function rolloutMetadataFromTranscript(transcript) { const payloads = transcript .split('\n') .filter((line) => line.trim().length > 0) .map((line) => JSON.parse(line)); const lastPayload = payloads[payloads.length - 1]; if (!lastPayload) { return { updatedAt: 'unknown', terminalState: 'unknown', }; } const terminalMetadata = lastPayload.terminal_metadata; const terminalState = terminalMetadata && typeof terminalMetadata === 'object' ? String(terminalMetadata.terminal_state ?? 'unknown') : 'unknown'; return { updatedAt: typeof lastPayload.updated_at === 'string' ? lastPayload.updated_at : 'unknown', terminalState, }; } function formatRawMemory(args) { return [ `rollout_id: ${args.rolloutId}`, `updated_at: ${args.updatedAt}`, `rollout_path: ${args.rolloutPath}`, `rollout_summary_file: ${args.rolloutSummaryFile}`, `terminal_state: ${args.terminalState}`, '', args.rawMemory.trimEnd(), '', ].join('\n'); } function formatRolloutSummary(args) { return [ `session_id: ${args.sessionId}`, `updated_at: ${args.updatedAt}`, `rollout_path: ${args.rolloutPath}`, `terminal_state: ${args.terminalState}`, '', args.rolloutSummary.trimEnd(), '', ].join('\n'); } function normalizedLayout(memory) { return { memoriesDir: normalizeLayoutPath(memory.layout.memoriesDir), sessionsDir: normalizeLayoutPath(memory.layout.sessionsDir), summaryFile: normalizeLayoutPath(memory.layout.summaryFile), }; } function memoryLayoutKey(memory) { const layout = normalizedLayout(memory); return `${layout.memoriesDir}\0${layout.sessionsDir}\0${layout.summaryFile}`; } function normalizeLayoutPath(value) { return value .split('/') .filter((part) => part.length > 0 && part !== '.') .join('/'); } function memoryGenerationSignature(generate) { return (0, stableJson_1.stableJsonStringify)(generate, { encodeFunction: (value) => `function:${value.name || 'anonymous'}`, encodeNonPlainObject: (value) => `object:${objectId(value)}`, }); } function objectId(value) { const existing = objectIds.get(value); if (existing) { return existing; } const id = nextObjectId++; objectIds.set(value, id); return id; } //# sourceMappingURL=generation.js.map