Show estimated prompt size in words
Adds a word count display to the AI prompt generation dialog. This gives
the user an estimate of the prompt's size, which is useful because
large prompts can exceed the context window limits of AI models.
The size is calculated by counting words in the generated prompt content,
which serves as a close approximation for the number of tokens. The count
is displayed next to the "Copy Prompt" button and is formatted as "N words"
for counts under 1000, or "X.Yk words" for larger counts.
This is especially useful after adding context selector in Change 499521
so user can pick context size for diffs and size will help with how large
prompt it was created.
Google-Bug-Id: b/437392245
Release-Notes: skip
Change-Id: I0532a9dfa989cdd8260d8f121d40a9c47fac1c80
diff --git a/polygerrit-ui/app/elements/change/gr-ai-prompt-dialog/gr-ai-prompt-dialog.ts b/polygerrit-ui/app/elements/change/gr-ai-prompt-dialog/gr-ai-prompt-dialog.ts
index a2c2e6d..26d6e9d 100644
--- a/polygerrit-ui/app/elements/change/gr-ai-prompt-dialog/gr-ai-prompt-dialog.ts
+++ b/polygerrit-ui/app/elements/change/gr-ai-prompt-dialog/gr-ai-prompt-dialog.ts
@@ -78,6 +78,8 @@
@state() private promptContent = '';
+ @state() private promptSize = '';
+
private readonly getChangeModel = resolve(this, changeModelToken);
private readonly restApiService = getAppContext().restApiService;
@@ -170,6 +172,14 @@
justify-content: space-between;
align-items: center;
}
+ .actions {
+ display: flex;
+ align-items: center;
+ gap: var(--spacing-l);
+ }
+ .size {
+ color: var(--deactivated-text-color);
+ }
.context-selector {
display: flex;
align-items: center;
@@ -246,10 +256,13 @@
You can also use it for an AI Agent as context (a reference
to a git change).
</div>
- <gr-button @click=${this.handleCopyPatch}>
- <gr-icon icon="content_copy" small></gr-icon>
- Copy Prompt
- </gr-button>
+ <div class="actions">
+ <div class="size">${this.promptSize}</div>
+ <gr-button @click=${this.handleCopyPatch}>
+ <gr-icon icon="content_copy" small></gr-icon>
+ Copy Prompt
+ </gr-button>
+ </div>
</div>`,
() => html`
<div class="info-text">
@@ -323,6 +336,7 @@
private updatePromptContent() {
if (!this.patchContent) {
this.promptContent = '';
+ this.promptSize = '';
return;
}
const template = PROMPT_TEMPLATES[this.selectedTemplate];
@@ -330,6 +344,20 @@
'{{patch}}',
this.patchContent
);
+ // Inserts a space before each capital letter to handle CamelCase
+ const textWithSpaces = this.promptContent.replace(/([A-Z])/g, ' $1');
+
+ // Splits by whitespace, symbols, and now slashes
+ const size = textWithSpaces
+ .split(/["\s.(){}[\]\\/-]+/)
+ .filter(Boolean).length;
+ if (size === 0) {
+ this.promptSize = '';
+ } else if (size < 1000) {
+ this.promptSize = `${size} words`;
+ } else {
+ this.promptSize = `${(size / 1000).toFixed(1)}k words`;
+ }
}
private async handleCopyPatch(e: Event) {
diff --git a/polygerrit-ui/app/elements/change/gr-ai-prompt-dialog/gr-ai-prompt-dialog_test.ts b/polygerrit-ui/app/elements/change/gr-ai-prompt-dialog/gr-ai-prompt-dialog_test.ts
index c72d0c3..699035e 100644
--- a/polygerrit-ui/app/elements/change/gr-ai-prompt-dialog/gr-ai-prompt-dialog_test.ts
+++ b/polygerrit-ui/app/elements/change/gr-ai-prompt-dialog/gr-ai-prompt-dialog_test.ts
@@ -14,7 +14,7 @@
suite('gr-ai-prompt-dialog test', () => {
let element: GrAiPromptDialog;
setup(async () => {
- stubRestApi('getPatchContent').returns(Promise.resolve('<patch>'));
+ stubRestApi('getPatchContent').returns(Promise.resolve('test code'));
element = await fixture(html`<gr-ai-prompt-dialog></gr-ai-prompt-dialog>`);
element.change = createParsedChange();
element.change.revisions['abc'].commit!.parents = [
@@ -24,6 +24,8 @@
},
];
element.patchNum = 1 as PatchSetNum;
+ element.patchContent = 'test code';
+ element.selectedTemplate = 'PATCH_ONLY';
await element.updateComplete;
});
@@ -42,9 +44,8 @@
<div class="template-options">
<label class="template-option">
<md-radio
- checked=""
name="template"
- tabindex="0"
+ tabindex="-1"
>
</md-radio>
Help me with review
@@ -59,8 +60,9 @@
</label>
<label class="template-option">
<md-radio
+ checked=""
name="template"
- tabindex="-1"
+ tabindex="0"
>
</md-radio>
Just patch content
@@ -111,28 +113,33 @@
code can be shared with AI. We recommend a thinking model.
You can also use it for an AI Agent as context (a reference
to a git change).
- </div>
- <gr-button>
- <gr-icon
- icon="content_copy"
- small=""
- >
- </gr-icon>
- Copy Prompt
- </gr-button>
- </div>
- </div>
- </section>
- <section class="footer">
- <span class="closeButtonContainer">
- <gr-button
- id="closeButton"
- link=""
- >
- Close
- </gr-button>
- </span>
- </section>`
+ </div>
+ <div class="actions">
+ <div class="size">
+ 2 words
+ </div>
+ <gr-button>
+ <gr-icon
+ icon="content_copy"
+ small=""
+ >
+ </gr-icon>
+ Copy Prompt
+ </gr-button>
+ </div>
+ </div>
+ </div>
+ </section>
+ <section class="footer">
+ <span class="closeButtonContainer">
+ <gr-button
+ id="closeButton"
+ link=""
+ >
+ Close
+ </gr-button>
+ </span>
+ </section>`
);
});
});