Publish Claude Code Binaries / Stage and publish binaries (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-arm64 (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build linux-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build windows-amd64 (push) Canceled after 0s
Sync Tutti Agent Skills / sync (push) Canceled after 0s
Windows Agent Adapters / Test Windows agent adapters (push) Canceled after 0s
Windows Daemon Adapters / Test Windows daemon adapters (push) Canceled after 0s
Publish Tutti App Runtime / Publish runtime catalog (push) Canceled after 0s
107 lines
2.9 KiB
TypeScript
107 lines
2.9 KiB
TypeScript
import type { WorkspaceFileReference } from "@tutti-os/workspace-file-reference/contracts";
|
|
|
|
export type AgentExternalPromptEntryResolution =
|
|
| {
|
|
disposition: "reference";
|
|
reference: WorkspaceFileReference;
|
|
sourceIndex: number;
|
|
}
|
|
| {
|
|
disposition: "prepare";
|
|
sourceIndex: number;
|
|
};
|
|
|
|
export type AgentExternalPromptEntryResolver = (
|
|
files: readonly File[]
|
|
) => readonly AgentExternalPromptEntryResolution[];
|
|
|
|
export type AgentResolvedExternalPromptEntry =
|
|
| {
|
|
disposition: "reference";
|
|
reference: WorkspaceFileReference;
|
|
sourceIndex: number;
|
|
}
|
|
| {
|
|
disposition: "prepare";
|
|
file: File;
|
|
sourceIndex: number;
|
|
};
|
|
|
|
export type AgentExternalPromptEntryInsertion =
|
|
| {
|
|
disposition: "reference";
|
|
reference: WorkspaceFileReference;
|
|
}
|
|
| {
|
|
disposition: "prepare";
|
|
files: File[];
|
|
};
|
|
|
|
export function resolveAgentExternalPromptEntries(
|
|
files: readonly File[],
|
|
resolver?: AgentExternalPromptEntryResolver | null
|
|
): AgentResolvedExternalPromptEntry[] {
|
|
if (!resolver) return files.map(preparedEntry);
|
|
|
|
let resolved: readonly AgentExternalPromptEntryResolution[];
|
|
try {
|
|
resolved = resolver(files);
|
|
} catch {
|
|
return files.map(preparedEntry);
|
|
}
|
|
|
|
const resultByIndex = new Map<number, AgentExternalPromptEntryResolution>();
|
|
for (const result of resolved) {
|
|
if (
|
|
!Number.isInteger(result.sourceIndex) ||
|
|
result.sourceIndex < 0 ||
|
|
result.sourceIndex >= files.length ||
|
|
resultByIndex.has(result.sourceIndex)
|
|
) {
|
|
return files.map(preparedEntry);
|
|
}
|
|
if (result.disposition === "reference" && !result.reference.path.trim()) {
|
|
return files.map(preparedEntry);
|
|
}
|
|
resultByIndex.set(result.sourceIndex, result);
|
|
}
|
|
if (resultByIndex.size !== files.length) return files.map(preparedEntry);
|
|
|
|
return files.map((file, sourceIndex) => {
|
|
const result = resultByIndex.get(sourceIndex)!;
|
|
return result.disposition === "reference"
|
|
? {
|
|
disposition: "reference" as const,
|
|
reference: result.reference,
|
|
sourceIndex
|
|
}
|
|
: preparedEntry(file, sourceIndex);
|
|
});
|
|
}
|
|
|
|
export function groupAgentExternalPromptEntryInsertions(
|
|
entries: readonly AgentResolvedExternalPromptEntry[]
|
|
): AgentExternalPromptEntryInsertion[] {
|
|
const insertions: AgentExternalPromptEntryInsertion[] = [];
|
|
for (const entry of entries) {
|
|
if (entry.disposition === "reference") {
|
|
insertions.push({
|
|
disposition: "reference",
|
|
reference: entry.reference
|
|
});
|
|
continue;
|
|
}
|
|
const previous = insertions.at(-1);
|
|
if (previous?.disposition === "prepare") {
|
|
previous.files.push(entry.file);
|
|
} else {
|
|
insertions.push({ disposition: "prepare", files: [entry.file] });
|
|
}
|
|
}
|
|
return insertions;
|
|
}
|
|
|
|
function preparedEntry(file: File, sourceIndex: number) {
|
|
return { disposition: "prepare" as const, file, sourceIndex };
|
|
}
|