f235b8ce90
- Move cmd/agentu/main.go → main.go (project root) - Move internal/llm/ → pkg/llm/ (leaf package, no internal deps) - Move internal/config/ → pkg/config/ (leaf package, no internal deps) - Update all import paths: agentu/internal/llm → agentu/pkg/llm (14 files) - Update all import paths: agentu/internal/config → agentu/pkg/config (3 files) - Update README: build/run commands, CLI flags section - agent/session/tools/tui stay in internal/ (app-specific business logic) Build: go build . | Test: go test ./... | Vet: go vet ./...
44 lines
1018 B
Go
44 lines
1018 B
Go
package llm
|
|
|
|
import "encoding/json"
|
|
|
|
const tokenEstimateCharRatio = 4
|
|
|
|
// EstimateTokens estimates the token cost of messages and tool definitions in a
|
|
// chat completion request. It intentionally uses a simple JSON-size heuristic:
|
|
// roughly four UTF-8 bytes per token plus a small per-message framing overhead.
|
|
func EstimateTokens(messages []Message, tools []Tool) int {
|
|
if len(messages) == 0 && len(tools) == 0 {
|
|
return 0
|
|
}
|
|
|
|
payload := struct {
|
|
Messages []Message `json:"messages,omitempty"`
|
|
Tools []Tool `json:"tools,omitempty"`
|
|
}{
|
|
Messages: messages,
|
|
Tools: tools,
|
|
}
|
|
data, err := json.Marshal(payload)
|
|
if err != nil {
|
|
return 0
|
|
}
|
|
|
|
return estimateBytesAsTokens(len(data)) + len(messages)*4
|
|
}
|
|
|
|
func estimateMessageTokens(msg Message) int {
|
|
data, err := json.Marshal(msg)
|
|
if err != nil {
|
|
return 0
|
|
}
|
|
return estimateBytesAsTokens(len(data)) + 4
|
|
}
|
|
|
|
func estimateBytesAsTokens(n int) int {
|
|
if n <= 0 {
|
|
return 0
|
|
}
|
|
return (n + tokenEstimateCharRatio - 1) / tokenEstimateCharRatio
|
|
}
|