tpmjs/apps/omega-mac/OmegaMac/Utilities/SanitizeToolName.swift
Thomas Davis 1cd44b4e97 feat: add Omega Mac native macOS SwiftUI chat app
Native macOS counterpart to the web Omega agent, connecting directly
to the OpenAI API and TPMJS tool registry (1M+ AI-ready tools).

- SwiftUI app targeting macOS 15+ with dark theme
- Full agentic loop: auto-discover tools via BM25, stream OpenAI
  responses, execute tools via remote sandbox, loop up to 10x
- SwiftData persistence for conversations, messages, tool runs
- Keychain storage for API keys and environment variables
- SSE streaming via URLSession.bytes with custom parser
- Actor-based services (OpenAIService, TPMJSRegistryService)
- NavigationSplitView layout with sidebar + chat detail
- MarkdownUI for rendering assistant responses
- Settings: API key, model picker, env vars, custom system prompt
- Keyboard shortcuts: Cmd+N new chat, Cmd+, settings, Enter send

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 21:29:39 +10:00

40 lines
1.3 KiB
Swift

import Foundation
/// Sanitize a tool ID to be a valid OpenAI function name.
/// Port of the web's sanitizeToolName logic.
/// OpenAI requires tool names to be <= 64 characters and match [a-zA-Z0-9_-].
func sanitizeToolName(_ name: String) -> String {
var sanitized = name
.replacingOccurrences(of: "@", with: "")
.replacingOccurrences(of: "/", with: "_")
.replacingOccurrences(of: "-", with: "_")
.replacingOccurrences(of: "::", with: "_")
// Remove any remaining invalid characters
sanitized = String(sanitized.unicodeScalars.filter { scalar in
CharacterSet.alphanumerics.contains(scalar) || scalar == "_"
})
// OpenAI API requires tool names <= 64 characters
if sanitized.count <= 64 {
return sanitized
}
// Truncate but try to keep the meaningful part (tool name at the end)
let last64 = String(sanitized.suffix(64))
if let first = last64.first, first.isLetter {
return last64
}
return String(sanitized.prefix(64))
}
/// Reverse lookup: find the original toolId from a sanitized name
/// by checking against loaded tool metadata.
func findToolId(sanitizedName: String, in tools: [String: ToolMeta]) -> String? {
for (_, meta) in tools {
if sanitizeToolName(meta.toolId) == sanitizedName {
return meta.toolId
}
}
return nil
}