RecordTools parses the tools from a raw JSON request and stores them in the session.
(rawJSON []byte, format string)
| 133 | |
| 134 | // RecordTools parses the tools from a raw JSON request and stores them in the session. |
| 135 | func (s *Session) RecordTools(rawJSON []byte, format string) { |
| 136 | tools := gjson.GetBytes(rawJSON, "tools") |
| 137 | if !tools.Exists() || !tools.IsArray() { |
| 138 | log.Debugf("[sessions] RecordTools: no tools array in request for session %s", s.ID) |
| 139 | return |
| 140 | } |
| 141 | |
| 142 | now := time.Now() |
| 143 | var parsed []observedtools.ObservedTool |
| 144 | |
| 145 | tools.ForEach(func(_, tool gjson.Result) bool { |
| 146 | var name string |
| 147 | var schemaRaw gjson.Result |
| 148 | |
| 149 | switch format { |
| 150 | case "openai": |
| 151 | name = tool.Get("function.name").String() |
| 152 | schemaRaw = tool.Get("function.parameters") |
| 153 | case "openai-responses": |
| 154 | name = tool.Get("name").String() |
| 155 | schemaRaw = tool.Get("parameters") |
| 156 | default: // claude |
| 157 | name = tool.Get("name").String() |
| 158 | schemaRaw = tool.Get("input_schema") |
| 159 | } |
| 160 | |
| 161 | if name == "" { |
| 162 | return true |
| 163 | } |
| 164 | |
| 165 | var schema map[string]any |
| 166 | if schemaRaw.Exists() && schemaRaw.Raw != "" { |
| 167 | _ = json.Unmarshal([]byte(schemaRaw.Raw), &schema) |
| 168 | } |
| 169 | |
| 170 | parsed = append(parsed, observedtools.ObservedTool{ |
| 171 | Name: name, |
| 172 | Schema: schema, |
| 173 | Format: format, |
| 174 | UpdatedAt: now, |
| 175 | }) |
| 176 | return true |
| 177 | }) |
| 178 | |
| 179 | if len(parsed) == 0 { |
| 180 | log.Debugf("[sessions] RecordTools: tools array present but 0 tools parsed for session %s (format=%s)", s.ID, format) |
| 181 | return |
| 182 | } |
| 183 | |
| 184 | s.mu.Lock() |
| 185 | defer s.mu.Unlock() |
| 186 | |
| 187 | // Only update tools if we have at least as many as before. |
| 188 | // Prevents partial tool lists from overwriting a complete snapshot. |
| 189 | if len(parsed) >= len(s.Tools) { |
| 190 | s.Tools = parsed |
| 191 | s.toolProfile = nil // invalidate cached profile |
| 192 | } |
no test coverage detected