-
Notifications
You must be signed in to change notification settings - Fork 132
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add ellipse on token limit exceed and flex layout options in PromptTemplateString #694
Changes from 3 commits
786833a
fa0aaae
606a689
265eb2a
5442319
2bc4e7b
e8c2420
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,7 +6,11 @@ | |
import { MarkdownTrace, TraceOptions } from "./trace" | ||
import { arrayify, assert, toStringList, trimNewlines } from "./util" | ||
import { YAMLStringify } from "./yaml" | ||
import { MARKDOWN_PROMPT_FENCE, PROMPT_FENCE } from "./constants" | ||
import { | ||
MARKDOWN_PROMPT_FENCE, | ||
MAX_TOKENS_ELLIPSE, | ||
PROMPT_FENCE, | ||
} from "./constants" | ||
import { parseModelIdentifier } from "./models" | ||
import { toChatCompletionUserMessage } from "./chat" | ||
import { errorMessage } from "./error" | ||
|
@@ -417,11 +421,11 @@ | |
await visitor.afterNode?.(node) | ||
} | ||
|
||
export interface PromptNodeRender { | ||
prompt: string | ||
userPrompt: string | ||
assistantPrompt: string | ||
images: PromptImage[] | ||
errors: unknown[] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The 'prompt' property in the 'PromptNodeRender' interface has been renamed to 'userPrompt'. This could potentially break any code that relies on the original 'prompt' property.
|
||
schemas: Record<string, JSONSchema> | ||
functions: ToolCallback[] | ||
fileMerges: FileMergeHandler[] | ||
|
@@ -550,20 +554,20 @@ | |
resolved?: string | ||
tokens?: number | ||
maxTokens?: number | ||
preview?: string | ||
}) => { | ||
if ( | ||
!n.error && | ||
n.resolved !== undefined && | ||
n.maxTokens !== undefined && | ||
n.tokens > n.maxTokens | ||
) { | ||
const value = n.resolved.slice( | ||
0, | ||
Math.floor((n.maxTokens * n.resolved.length) / n.tokens) | ||
) | ||
n.resolved = value | ||
const end = Math.floor((n.maxTokens * n.resolved.length) / n.tokens) | ||
const value = n.resolved.slice(0, end) + MAX_TOKENS_ELLIPSE | ||
n.resolved = n.preview = value | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The code is slicing the
|
||
n.tokens = estimateTokens(value, encoder) | ||
truncated = true | ||
trace.log(`truncated text to ${n.tokens} tokens`) | ||
} | ||
} | ||
|
||
|
@@ -574,12 +578,15 @@ | |
n.maxTokens !== undefined && | ||
n.tokens > n.maxTokens | ||
) { | ||
n.resolved.content = n.resolved.content.slice( | ||
0, | ||
Math.floor((n.maxTokens * n.resolved.content.length) / n.tokens) | ||
const end = Math.floor( | ||
(n.maxTokens * n.resolved.content.length) / n.tokens | ||
) | ||
n.resolved.content = | ||
n.resolved.content.slice(0, end) + MAX_TOKENS_ELLIPSE | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The code is slicing the
|
||
n.tokens = estimateTokens(n.resolved.content, encoder) | ||
n.preview = n.resolved.content | ||
truncated = true | ||
trace.log(`truncated def ${n.name} to ${n.tokens} tokens`) | ||
} | ||
} | ||
|
||
|
@@ -593,6 +600,20 @@ | |
return truncated | ||
} | ||
|
||
async function flexPromptNode( | ||
model: string, | ||
node: PromptNode, | ||
options?: TraceOptions | ||
): Promise<boolean> { | ||
const FLEX_BASIS_DEFAULT = 1 | ||
const FLEX_GROW_DEFAULT = Infinity | ||
const { trace } = options || {} | ||
const encoder = await resolveTokenEncoder(model) | ||
let flexed = false | ||
|
||
return flexed | ||
} | ||
|
||
async function tracePromptNode( | ||
trace: MarkdownTrace, | ||
root: PromptNode, | ||
|
@@ -640,7 +661,11 @@ | |
const truncated = await truncatePromptNode(model, node, options) | ||
if (truncated) await tracePromptNode(trace, node, { label: "truncated" }) | ||
|
||
let prompt = "" | ||
const flexed = await flexPromptNode(model, node, options) | ||
if (flexed) await tracePromptNode(trace, node, { label: "flexed" }) | ||
|
||
let systemPrompt = "" | ||
let userPrompt = "" | ||
let assistantPrompt = "" | ||
const images: PromptImage[] = [] | ||
const errors: unknown[] = [] | ||
|
@@ -655,12 +680,12 @@ | |
text: async (n) => { | ||
if (n.error) errors.push(n.error) | ||
const value = n.resolved | ||
if (value != undefined) prompt += value + "\n" | ||
if (value != undefined) userPrompt += value + "\n" | ||
}, | ||
def: async (n) => { | ||
if (n.error) errors.push(n.error) | ||
const value = n.resolved | ||
if (value !== undefined) prompt += renderDefNode(n) + "\n" | ||
if (value !== undefined) userPrompt += renderDefNode(n) + "\n" | ||
}, | ||
assistant: async (n) => { | ||
if (n.error) errors.push(n.error) | ||
|
@@ -670,7 +695,7 @@ | |
stringTemplate: async (n) => { | ||
if (n.error) errors.push(n.error) | ||
const value = n.resolved | ||
if (value != undefined) prompt += value + "\n" | ||
if (value != undefined) userPrompt += value + "\n" | ||
}, | ||
image: async (n) => { | ||
if (n.error) errors.push(n.error) | ||
|
@@ -691,8 +716,8 @@ | |
const value = n.resolved | ||
if (value) { | ||
for (const [filename, content] of Object.entries(value)) { | ||
prompt += content | ||
prompt += "\n" | ||
userPrompt += content | ||
userPrompt += "\n" | ||
if (trace) | ||
trace.detailsFenced( | ||
`📦 import template ${filename}`, | ||
|
@@ -727,7 +752,7 @@ | |
${trimNewlines(schemaText)} | ||
\`\`\` | ||
` | ||
prompt += text | ||
userPrompt += text | ||
n.tokens = estimateTokens(text, encoder) | ||
if (trace && format !== "json") | ||
trace.detailsFenced( | ||
|
@@ -771,7 +796,7 @@ | |
|
||
const fods = fileOutputs?.filter((f) => !!f.description) | ||
if (fods?.length > 0) { | ||
prompt += ` | ||
userPrompt += ` | ||
## File generation rules | ||
|
||
When generating files, use the following rules which are formatted as "file glob: description": | ||
|
@@ -782,15 +807,15 @@ | |
} | ||
|
||
const messages: ChatCompletionMessageParam[] = [ | ||
toChatCompletionUserMessage(prompt, images), | ||
toChatCompletionUserMessage(userPrompt, images), | ||
] | ||
if (assistantPrompt) | ||
messages.push(<ChatCompletionAssistantMessageParam>{ | ||
role: "assistant", | ||
content: assistantPrompt, | ||
}) | ||
const res = { | ||
prompt, | ||
const res = <PromptNodeRender>{ | ||
userPrompt, | ||
assistantPrompt, | ||
images, | ||
schemas, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The variable 'prompt' has been renamed to 'userPrompt'. This could potentially break any code that relies on the original 'prompt' variable.