perf: token estimation memoization + tool catalog cache
ober
2bd0e4f765f962eb0c7f5fa3f50c37b7c9c2fda7
--- a/src/jcode/tool/registry.ss +++ b/src/jcode/tool/registry.ss @@ -34,6 +34,9 @@ (def logger (make-logger "tools")) (def *tools* (make-hash-table)) +(def *tool-version* (make-parameter 0)) +(def (bump-tool-version!) + (*tool-version* (+ (*tool-version*) 1))) ;; ---- Mode (plan vs build) ---- ;; @@ -85,9 +88,11 @@ (def (user-disable-tool! name) (let ((lst (*user-disabled-tools*))) (unless (member name lst) - (*user-disabled-tools* (cons name lst))))) + (*user-disabled-tools* (cons name lst)))) + (bump-tool-version!)) (def (user-enable-tool! name) - (*user-disabled-tools* (remove (lambda (x) (equal? x name)) (*user-disabled-tools*)))) + (*user-disabled-tools* (remove (lambda (x) (equal? x name)) (*user-disabled-tools*))) + (bump-tool-version!)) (def (user-disabled-tools-list) (*user-disabled-tools*)) @@ -121,7 +126,8 @@ `(("name" . ,name) ("description" . ,description) ("schema" . ,schema) - ("handler" . ,handler))))) + ("handler" . ,handler)))) + (bump-tool-version!)) (def (make-hash-table-from-alist pairs) (let ((ht (make-hash-table))) @@ -181,17 +187,43 @@ (catch (_e) #f))) truncated))))))))))))) +;; --- Tool schema cache --- +;; Rebuilding the catalog for every request wastes ~20% of local-model +;; prompt build time. Cache it; invalidate on every registry mutation. +(def *schema-cache-version* (make-parameter -1)) +(def *schema-cache-result* (make-parameter '())) +(def *schema-cache-compacted-version* (make-parameter -1)) +(def *schema-cache-compacted* (make-parameter '())) + (def (get-tool-schemas) - (let ((mapper (if (current-compact-tool-schemas) - tool->compact-openai-schema - tool->openai-schema))) - (map mapper - (filter (lambda (t) - (and t - (not (hash-get t "internal")) - (mode-allows-tool? (hash-ref t "name" "")))) - (map (lambda (name) (hash-get *tools* name)) - (list-tools)))))) + (let* ((version (*tool-version*)) + (compact (current-compact-tool-schemas)) + (cache-version (cond + (compact (*schema-cache-compacted-version*)) + (else (*schema-cache-version*)))) + (cached (cond + (compact (*schema-cache-compacted*)) + (else (*schema-cache-result*))))) + (if (= version cache-version) + cached + (let* ((mapper (if compact + tool->compact-openai-schema + tool->openai-schema)) + (result (map mapper + (filter (lambda (t) + (and t + (not (hash-get t "internal")) + (mode-allows-tool? (hash-ref t "name" "")))) + (map (lambda (name) (hash-get *tools* name)) + (list-tools)))))) + (if compact + (begin + (*schema-cache-compacted* result) + (*schema-cache-compacted-version* version)) + (begin + (*schema-cache-result* result) + (*schema-cache-version* version))) + result)))) (def (list-tools) (filter (lambda (name) (not (tool-disabled? name)))