All blocks $0.0007 (in: $0.0001, out: $0.0006)
Block
Cost + token meter
Compose footer for billing-conscious apps. Live token estimate against a budget threshold; running session cost in the corner.
Live tokens · running cost · per-message estimate
This session $0.06 this session
Sent: 3 · estimated cost of next message:
<!-- Status bar showing running session cost -->
<div class="flex justify-end">
<pk-cost-display
display="session-summary"
currency="USD"
[costPrecision]="2"
[inputTokens]="totalInputTokens()"
[outputTokens]="totalOutputTokens()"
[inputPricePer1M]="2.5"
[outputPricePer1M]="10.0"
/>
</div>
<!-- Compose row with live token meter inside the actions footer -->
<!-- spartan input-group: textarea plus a block-end addon -->
<div hlmInputGroup class="rounded-3xl">
<textarea
hlmInputGroupTextarea
placeholder="Type a prompt..."
[value]="value()"
(input)="value.set($any($event.target).value)"
(keydown.enter)="onEnter($event)"
></textarea>
<div hlmInputGroupAddon align="block-end" class="justify-between gap-3">
<pk-token-counter
display="progress"
[text]="value()"
[limit]="800"
class="flex-1"
/>
<button hlmBtn size="icon-sm" class="rounded-full" hlmTooltip="Send" (click)="onSend()">
<ng-icon name="lucideArrowUp" class="text-[length:--spacing(3)]" />
</button>
</div>
</div>
<!-- Pre-send estimate of just this message -->
<pk-cost-display
display="detailed"
[inputTokens]="estimatedTokens()"
[outputTokens]="estimatedTokens() * 2"
[inputPricePer1M]="2.5"
[outputPricePer1M]="10.0"
/>
// Component
protected readonly value = signal('');
protected readonly totalInputTokens = signal(2_400);
protected readonly totalOutputTokens = signal(5_180);
protected readonly estimatedTokens = computed(() =>
Math.max(1, Math.ceil(this.value().length / 4))
);
protected onEnter(event: Event): void {
if ((event as KeyboardEvent).shiftKey) return; // Shift+Enter adds a line
event.preventDefault();
this.onSend();
}
protected onSend(): void {
const tokens = this.estimatedTokens();
this.totalInputTokens.update(v => v + tokens);
this.totalOutputTokens.update(v => v + tokens * 2);
this.value.set('');
}