@openai/agents-core
Version:
The OpenAI Agents SDK is a lightweight yet powerful framework for building multi-agent workflows.
115 lines • 5.48 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.selectPendingInputForAdmission = selectPendingInputForAdmission;
exports.mapPendingInputAfterContextProcessing = mapPendingInputAfterContextProcessing;
exports.commitPendingInput = commitPendingInput;
exports.hasUnpersistedRunInput = hasUnpersistedRunInput;
const errors_1 = require("../errors.js");
const items_1 = require("../items.js");
const items_2 = require("./items.js");
const sessionPersistence_1 = require("./sessionPersistence.js");
/**
* Resolves which staged occurrences reached the model after filtering.
*/
function selectPendingInputForAdmission(pendingItems, preparation) {
if (pendingItems.length === 0) {
return [];
}
const pendingByRawItem = new Map();
for (const item of pendingItems) {
pendingByRawItem.set(item.rawItem, item);
}
for (const [index, sourceItem] of preparation.sourceItems.entries()) {
if (sourceItem &&
pendingByRawItem.has(sourceItem) &&
preparation.sourceMatchKinds[index] === 'fallback') {
throw new errors_1.UserError('callModelInputFilter cannot safely associate a reconstructed item with pending RunState input. Preserve the input item object, return an unchanged copy, or omit the pending item.');
}
}
const pendingKeys = new Set(pendingItems.map((item) => (0, items_2.getAgentInputItemKey)(item.rawItem)));
for (const key of pendingKeys) {
const candidates = preparation.turnInput.filter((item) => (0, items_2.getAgentInputItemKey)(item) === key);
const reconstructedMatches = preparation.sourceItems.flatMap((sourceItem, index) => sourceItem &&
(0, items_2.getAgentInputItemKey)(sourceItem) === key &&
preparation.sourceMatchKinds[index] === 'content'
? [sourceItem]
: []);
const hasPendingCandidate = candidates.some((candidate) => pendingByRawItem.has(candidate));
const hasNonPendingCandidate = candidates.some((candidate) => !pendingByRawItem.has(candidate));
if (reconstructedMatches.length > 0 &&
reconstructedMatches.length < candidates.length &&
hasPendingCandidate &&
hasNonPendingCandidate) {
throw new errors_1.UserError('callModelInputFilter cannot safely associate a reconstructed item with pending RunState input. Preserve the input item object, return an unchanged copy, or omit the pending item.');
}
}
const admitted = [];
const acceptedIds = new Set();
for (const [index, sourceItem] of preparation.sourceItems.entries()) {
if (!sourceItem) {
continue;
}
const pendingItem = pendingByRawItem.get(sourceItem);
if (!pendingItem || acceptedIds.has(pendingItem.inputId)) {
continue;
}
const persistedItem = preparation.persistedItems[index];
if (!persistedItem) {
continue;
}
acceptedIds.add(pendingItem.inputId);
const preservesPreparedItem = preparation.preserveInputIdentity &&
preparation.sourceMatchKinds[index] === 'identity' &&
(0, items_2.getAgentInputItemKey)(pendingItem.rawItem) ===
(0, items_2.getAgentInputItemKey)(persistedItem);
admitted.push(preservesPreparedItem
? pendingItem
: new items_1.RunInputItem(structuredClone(persistedItem), pendingItem.agent, pendingItem.inputId));
}
return admitted;
}
/**
* Preserves staged occurrence identity through sandbox capability processing.
*/
function mapPendingInputAfterContextProcessing(pendingItems, preparedItems, processedItems) {
if (pendingItems.length === 0 || preparedItems === processedItems) {
return pendingItems;
}
return (0, sessionPersistence_1.mapOwnedInputItemsAfterContextProcessing)(preparedItems, processedItems, pendingItems.map((item) => item.rawItem)).map(({ item, ownerIndex }) => {
const pendingItem = pendingItems[ownerIndex];
return new items_1.RunInputItem(item, pendingItem.agent, pendingItem.inputId);
});
}
/**
* Commits accepted occurrences to RunState and leaves omitted occurrences pending.
*/
function commitPendingInput(state, preparedItems, admittedItems, sourceItems) {
if (preparedItems.length === 0) {
return;
}
const admittedIds = new Set(admittedItems.map((item) => item.inputId));
const sourceItemSet = new Set(sourceItems);
const preparedQueueIsIntact = sourceItems.every((item, index) => state._pendingInput[index] === item);
const newlyStagedItems = preparedQueueIsIntact
? state._pendingInput.slice(sourceItems.length)
: state._pendingInput.filter((item) => !sourceItemSet.has(item));
state._generatedItems.push(...admittedItems);
state._pendingInput = [
...(preparedQueueIsIntact
? preparedItems
.filter((item) => !admittedIds.has(item.inputId))
.map((item) => item.rawItem)
: []),
...structuredClone(newlyStagedItems),
];
}
/**
* Returns whether a committed input occurrence still belongs to the unpersisted
* suffix for the current local-session turn.
*/
function hasUnpersistedRunInput(state) {
return state._generatedItems
.slice(state._currentTurnPersistedItemCount)
.some((item) => item instanceof items_1.RunInputItem);
}
//# sourceMappingURL=pendingInput.js.map