refactor: restructure project layout — main.go to root, llm+config to pkg/
- 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 ./...
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user