Add canonical GameCult text documents

This commit is contained in:
Meta Vens 2026-06-04 19:55:33 +01:00
commit a71df3452a
8 changed files with 315 additions and 44 deletions

View file

@ -11,13 +11,16 @@ import {
buildEpiphanyIdentityRegistry,
ContextBuilder,
createStateStorage,
ensureGameCultTextDocument,
ensureRepoFaceInitialized,
getRepoDiscordIdentityAllowedChannelIds,
faceRegistryAsRepoDiscordRegistry,
ODIN_VERSE_POEM_DOCUMENT_ID,
projectRepoFaceSleepCycleForNow,
applyVoidSelfStateOperation,
loadFaceIdentityRegistry,
loadVoidSelfStateTypedDocuments,
renderGameCultStructuredTextDocument,
REPO_FACE_HEARTBEAT_SCHEMA_VERSION,
type RepoFaceRestSnapshot,
resolveRepoFaceStatePath,
@ -556,6 +559,10 @@ async function queueRepoFaceTurn(input: {
? renderNativePersonaBodySurface(identity)
: renderRepoFaceRepoActivitySurface(identity, input.config);
const globalAgentDoctrine = await loadGlobalAgentDoctrine();
const colossusOdinDoctrine = await renderColossusOdinDoctrine({
displayName: identity.displayName,
repoName: identity.repoName,
});
const conversationMemorySurface = renderRepoFaceConversationTranscript({
identity,
recentMessages,
@ -579,6 +586,7 @@ async function queueRepoFaceTurn(input: {
jurisdictionDive: buildJurisdictionDiveDirective(identity, input.participant),
githubActionsEnabled: input.config.repoFaceGithubActionsEnabled,
globalAgentDoctrine,
colossusOdinDoctrine,
});
const imageAttachments = collectPromptImageAttachments([
recentMessages,
@ -1834,18 +1842,15 @@ function buildHeartbeatPrompt(input: {
jurisdictionDive: JurisdictionDiveDirective;
githubActionsEnabled: boolean;
globalAgentDoctrine: string;
colossusOdinDoctrine: string;
}): string {
const colossusOdinDoctrine = loadPromptTemplate("repo-face-colossus-odin-doctrine.prompt.md", {
displayName: input.identity.displayName,
repoName: input.identity.repoName,
});
return loadPromptTemplate("repo-face-turn.prompt.md", {
displayName: input.identity.displayName,
identityId: input.identity.id,
repoName: input.identity.repoName,
identityDoctrine: renderRepoCharacterIdentityDoctrine(input.identity),
globalAgentDoctrine: input.globalAgentDoctrine,
colossusOdinDoctrine,
colossusOdinDoctrine: input.colossusOdinDoctrine,
channelId: input.channelId,
memorySurface: input.memorySurface ?? `- ${input.identity.displayName} has no strong personal memory surface yet. Let the attached conversation and repo evidence wake something specific.`,
repoActivitySurface: input.repoActivitySurface ?? "- No recent home repo activity was attached for this turn.",
@ -1881,6 +1886,23 @@ function buildHeartbeatPrompt(input: {
});
}
async function renderColossusOdinDoctrine(input: {
displayName: string;
repoName: string;
}): Promise<string> {
const poem = await ensureGameCultTextDocument(ODIN_VERSE_POEM_DOCUMENT_ID);
const odinVersePoem = renderGameCultStructuredTextDocument(poem, {
halfLineSeparator: " ",
stanzaSeparator: "\n\n",
});
return loadPromptTemplate("repo-face-colossus-odin-doctrine.prompt.md", {
displayName: input.displayName,
repoName: input.repoName,
odinVersePoem,
});
}
async function assembleRepoFaceTurnPrompt(input: {
config: ReturnType<typeof loadConfig>;
identityId: string;
@ -1957,6 +1979,10 @@ async function assembleRepoFaceTurnPrompt(input: {
);
const repoActivitySurface = renderRepoFaceRepoActivitySurface(identity, input.config);
const globalAgentDoctrine = await loadGlobalAgentDoctrine();
const colossusOdinDoctrine = await renderColossusOdinDoctrine({
displayName: identity.displayName,
repoName: identity.repoName,
});
const conversationMemorySurface = input.conversationSurfacePath
? await readOptionalMemorySurface(input.conversationSurfacePath)
: renderRepoFaceConversationTranscript({
@ -1986,6 +2012,7 @@ async function assembleRepoFaceTurnPrompt(input: {
jurisdictionDive: buildJurisdictionDiveDirective(identity, participant),
githubActionsEnabled: input.config.repoFaceGithubActionsEnabled,
globalAgentDoctrine,
colossusOdinDoctrine,
});
if (input.outPath) {

View file

@ -0,0 +1,66 @@
import {
GAMECULT_TEXT_DOCUMENT_STORE_PATH,
ODIN_VERSE_POEM_DOCUMENT_ID,
ensureGameCultTextDocumentSet,
loadGameCultTextDocumentSet,
renderGameCultStructuredTextDocument,
renderNightwingMarqueeLine,
} from "@voidbot/core";
function readArgValue(name: string): string | undefined {
const index = process.argv.indexOf(name);
if (index === -1) {
return undefined;
}
return process.argv[index + 1];
}
async function main(): Promise<void> {
const storePath = readArgValue("--store") ?? GAMECULT_TEXT_DOCUMENT_STORE_PATH;
const checkOnly = process.argv.includes("--check");
const preview = process.argv.includes("--preview");
const marqueePreview = process.argv.includes("--marquee-preview");
const documentSet = checkOnly
? await loadGameCultTextDocumentSet(storePath)
: await ensureGameCultTextDocumentSet(storePath);
const poem = documentSet.documents.find((document) => document.id === ODIN_VERSE_POEM_DOCUMENT_ID);
if (!poem) {
throw new Error(`Missing canonical document ${ODIN_VERSE_POEM_DOCUMENT_ID} in ${storePath}.`);
}
console.log(JSON.stringify({
ok: true,
mode: checkOnly ? "check" : "seed",
storePath,
owner: documentSet.owner,
documentCount: documentSet.documents.length,
firstDocument: {
id: poem.id,
title: poem.title,
author: poem.author,
lineCount: poem.lines.filter((line) => !(line.length === 1 && line[0] === "[stanza]")).length,
stanzaBreaks: poem.lines.filter((line) => line.length === 1 && line[0] === "[stanza]").length,
},
}, null, 2));
if (preview) {
console.log("\n--- poem preview ---");
console.log(renderGameCultStructuredTextDocument(poem));
}
if (marqueePreview) {
console.log("\n--- Nightwing marquee preview ---");
for (const line of poem.lines) {
console.log(line.length === 1 && line[0] === "[stanza]"
? ""
: renderNightwingMarqueeLine(line));
}
}
}
main().catch((error) => {
console.error(error instanceof Error ? error.stack ?? error.message : String(error));
process.exitCode = 1;
});