Skip to content

Commit

Permalink
generating messages
Browse files Browse the repository at this point in the history
  • Loading branch information
pelikhan committed Oct 24, 2024
1 parent a1ff114 commit 541919a
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 63 deletions.
33 changes: 32 additions & 1 deletion packages/core/src/chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import { createChatTurnGenerationContext } from "./runpromptcontext"
import { dedent } from "./indent"
import { traceLanguageModelConnection } from "./models"
import {
ChatCompletionAssistantMessageParam,
ChatCompletionContentPartImage,
ChatCompletionMessageParam,
ChatCompletionResponse,
Expand Down Expand Up @@ -578,7 +579,11 @@ async function processChatMessage(
throw new Error(
"system messages not supported for chat participants"
)
trace.detailsFenced(`💬 message`, userPrompt, "markdown")
renderMessagesToMarkdown(participantMessages)
trace.details(
`💬 messages (${participantMessages.length})`,
renderMessagesToMarkdown(participantMessages)
)
messages.push(...participantMessages)
needsNewTurn = true
} else trace.item("no message")
Expand Down Expand Up @@ -790,3 +795,29 @@ export function tracePromptResult(trace: MarkdownTrace, resp: RunPromptResult) {
"\n\n" + HTMLEscape(prettifyMarkdown(text)) + "\n\n"
)
}

export function appendUserMessage(
messages: ChatCompletionMessageParam[],
content: string
) {
const last = messages.at(-1) as ChatCompletionUserMessageParam
if (last?.role === "user") last.content += content + "\n"
else
messages.push({
role: "user",
content,
} as ChatCompletionUserMessageParam)
}

export function appendAssistantMessage(
messages: ChatCompletionMessageParam[],
content: string
) {
const last = messages.at(-1) as ChatCompletionAssistantMessageParam
if (last?.role === "assistant") last.content += content
else
messages.push({
role: "assistant",
content,
} satisfies ChatCompletionAssistantMessageParam)
}
54 changes: 17 additions & 37 deletions packages/core/src/expander.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Project, PromptScript } from "./ast"
import { assert, normalizeFloat, normalizeInt } from "./util"
import { MarkdownTrace } from "./trace"
import { errorMessage, isCancelError } from "./error"
import { errorMessage, isCancelError, NotSupportedError } from "./error"
import {
JS_REGEX,
MAX_TOOL_CALLS,
Expand Down Expand Up @@ -293,10 +293,18 @@ export async function expandTemplate(
if (sysr.fileOutputs) fileOutputs.push(...sysr.fileOutputs)
if (sysr.logs?.length)
trace.details("📝 console.log", sysr.logs)
if (sysr.text) {
systemMessage.content +=
SYSTEM_FENCE + "\n" + sysr.text + "\n"
trace.fence(sysr.text, "markdown")
for (const smsg of sysr.messages) {
if (
smsg.role === "user" &&
typeof smsg.content === "string"
) {
systemMessage.content +=
SYSTEM_FENCE + "\n" + smsg.content + "\n"
trace.fence(smsg.content, "markdown")
} else
throw new NotSupportedError(
"only string user messages supported in system"
)
}
if (sysr.aici) {
trace.fence(sysr.aici, "yaml")
Expand Down Expand Up @@ -328,50 +336,22 @@ export async function expandTemplate(
const schemaTs = JSONSchemaStringifyToTypeScript(responseSchema, {
typeName,
})
messages.unshift({
role: "system",
content: `You are a service that translates user requests
systemMessage.content += `You are a service that translates user requests
into JSON objects of type "${typeName}"
according to the following TypeScript definitions:
\`\`\`ts
${schemaTs}
\`\`\``,
})
\`\`\``
} else if (responseType === "json_object") {
messages.unshift({
role: "system",
content: `Answer using JSON.`,
})
systemMessage.content += SYSTEM_FENCE + "Answer using JSON.\n"
} else if (responseType === "json_schema") {
if (!responseSchema)
throw new Error(`responseSchema is required for json_schema`)
// try conversion
toStrictJSONSchema(responseSchema)
}
if (systemMessage.content) messages.unshift(systemMessage)

if (prompt.assistantText) {
trace.detailsFenced("🤖 assistant", prompt.assistantText, "markdown")
const assistantMessage: ChatCompletionAssistantMessageParam = {
role: "assistant",
content: prompt.assistantText,
}
messages.push(assistantMessage)
}
if (prompt.systemText) {
trace.detailsFenced("👾 system", prompt.systemText, "markdown")
const systemMessage: ChatCompletionSystemMessageParam = {
role: "system",
content: prompt.systemText,
}
// insert system messages after the last system role message in messages
// assume system messages are at the start
let li = -1
for (let li = 0; li < messages.length; li++)
if (messages[li].role === "system") break
messages.splice(li, 0, systemMessage)
}

messages.push(...prompt.messages)
trace.endDetails()

return {
Expand Down
24 changes: 4 additions & 20 deletions packages/core/src/promptdom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,11 @@ import {
TEMPLATE_ARG_FILE_MAX_TOKENS,
} from "./constants"
import { parseModelIdentifier } from "./models"
import { toChatCompletionUserMessage } from "./chat"
import { appendAssistantMessage, appendUserMessage } from "./chat"
import { errorMessage } from "./error"
import { tidyData } from "./tidy"
import { dedent } from "./indent"
import {
ChatCompletionAssistantMessageParam,
ChatCompletionMessageParam,
ChatCompletionSystemMessageParam,
ChatCompletionUserMessageParam,
Expand Down Expand Up @@ -950,24 +949,9 @@ export async function renderPromptNode(
content,
} as ChatCompletionSystemMessageParam)
}
const appendUser = (content: string) => {
const last = messages.at(-1) as ChatCompletionUserMessageParam
if (last?.role === "user") last.content += content + "\n"
else
messages.push({
role: "user",
content,
} as ChatCompletionUserMessageParam)
}
const appendAssistant = (content: string) => {
const last = messages.at(-1) as ChatCompletionAssistantMessageParam
if (last?.role === "assistant") last.content += content
else
messages.push({
role: "assistant",
content,
} satisfies ChatCompletionAssistantMessageParam)
}
const appendUser = (content: string) => appendUserMessage(messages, content)
const appendAssistant = (content: string) =>
appendAssistantMessage(messages, content)

const images: PromptImage[] = []
const errors: unknown[] = []
Expand Down
17 changes: 12 additions & 5 deletions packages/core/src/runpromptcontext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import {
createSchemaNode,
createStringTemplateNode,
createTextNode,
createSystemNode,
renderPromptNode,
createOutputProcessor,
createFileMerge,
Expand Down Expand Up @@ -676,10 +675,18 @@ export function createChatGenerationContext(
fileOutputs.push(...sysr.fileOutputs)
if (sysr.logs?.length)
runTrace.details("📝 console.log", sysr.logs)
if (sysr.text) {
systemMessage.content +=
SYSTEM_FENCE + "\n" + sysr.text + "\n"
runTrace.fence(sysr.text, "markdown")
for (const smsg of sysr.messages) {
if (
smsg.role === "user" &&
typeof smsg.content === "string"
) {
systemMessage.content +=
SYSTEM_FENCE + "\n" + smsg.content + "\n"
runTrace.fence(smsg.content, "markdown")
} else
throw new NotSupportedError(
"only string user messages supported in system"
)
}
if (sysr.aici) {
runTrace.fence(sysr.aici, "yaml")
Expand Down

0 comments on commit 541919a

Please sign in to comment.