Skip to content

Commit 99d5679

Browse files
ADFA-6318 | Describe native tool calling in the AI-Agent-OpenAI README (#121)
1 parent 12387c5 commit 99d5679

1 file changed

Lines changed: 31 additions & 12 deletions

File tree

‎plugins/AI-Agent-OpenAI/README.md‎

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -116,13 +116,30 @@ via CodeOnTheGo's Plugin Manager, then restart the IDE.
116116

117117
## Native function calling
118118

119-
Not implemented, deliberately. This backend declares `HistoryCapableBackend` but
120-
not `ToolCallingBackend`, so ai-core streams it the whole conversation and the
121-
agent loop drives tools through a text envelope in the system prompt, which is
122-
provider-agnostic. Declaring `ToolCallingBackend` without native function calling
123-
would leave the caller waiting on a call this backend never makes. The system
124-
prompt also tells the model not to use its own function-calling channel, since
125-
nothing reads it.
119+
This backend declares `ToolCallingBackend`, so ai-core calls
120+
`generateStreamingWithTools` and the agent's tools travel through the
121+
Chat Completions function-calling API rather than a text envelope in the reply
122+
(ADFA-5410). Declared tools arrive already structured, so a file whose contents
123+
carry quotes or newlines cannot break the call.
124+
125+
- **Request.** Each tool is sent in `tools[]` as `{"type":"function","function":{name, description, parameters}}`
126+
(`OpenAiToolProtocol`). `tool_choice` is sent only when ai-core names a required
127+
tool (`EXTRA_PARAM_REQUIRED_TOOL`); a server that refuses it is retried once
128+
without it, under the same rule as the other 400 retries (`RequestTuning`).
129+
- **Stream.** `tool_calls` deltas are joined by index (`SseChunk`,
130+
`OpenAiToolProtocol.CallAccumulator`) and reported through `onToolCall` once the
131+
stream ends, so a call a retry replaced never reaches the caller. A call with no
132+
name or unparseable arguments is dropped.
133+
- **Results.** `ChatMessage` gives an assistant turn no way to carry `tool_calls`,
134+
and a `tool` role is only legal after one, so tool results go back as `user` turns.
135+
- **Prompt.** ai-core sees the backend calls tools natively and passes no text call
136+
syntax, so `tools.yml`'s `native` format is sent. The text protocol, and its
137+
`no_native_channel` line, is not used by this backend.
138+
- **Servers without function calling.** If a server refuses the `tools` declaration
139+
(400, 404 or 422 naming a tool field as unsupported), the turn is retried with no
140+
tools and a Toast says the agent cannot call tools on that server. The refusal is
141+
remembered per base URL, so only the first turn pays for it. The prompt for that
142+
run was built for native calling, so the model answers in prose.
126143

127144
## System prompt config
128145

@@ -169,10 +186,12 @@ Every source file sits in a package named for its layer; nothing is loose at the
169186
root of `com/itsaky/androidide/plugins/aiagentopenai/`.
170187

171188
- `plugin/OpenAiPlugin.kt` — plugin entry point; registers the backend with ai-core
172-
- `backend/OpenAiBackend.kt` — the HTTP transport, SSE streaming and model catalog
173-
- `backend/OpenAiRequestBuilder.kt` — `messages[]` mapping and request JSON (pure)
174-
- `backend/RequestTuning.kt` — reasoning-model parameters and the 400-retry rule (pure)
175-
- `backend/SseChunk.kt` — one line of the token stream (pure)
189+
- `backend/OpenAiBackend.kt` — SSE streaming, native tool calling and the model catalog
190+
- `backend/OpenAiHttpClient.kt` — the HTTP transport
191+
- `backend/OpenAiRequestBuilder.kt` — `messages[]` mapping and request JSON, including `tools` (pure)
192+
- `backend/OpenAiToolProtocol.kt` — `tools[]`, `tool_choice` and the streamed `tool_calls` accumulator (pure)
193+
- `backend/RequestTuning.kt` — reasoning-model parameters, the 400-retry rule and tool-refusal detection (pure)
194+
- `backend/SseChunk.kt` — one line of the token stream, text or `tool_calls` deltas (pure)
176195
- `backend/ModelCatalogFilter.kt` — splits one catalog into the chat and embedding pickers (pure)
177196
- `backend/OpenAiEmbeddingProtocol.kt` — the `/v1/embeddings` body, batching and index-ordered reply (pure)
178197
- `errors/OpenAiErrorFormatter.kt` — turns a failure into one translated sentence
@@ -188,7 +207,7 @@ root of `com/itsaky/androidide/plugins/aiagentopenai/`.
188207
- `logging/` — `LOG_PREFIX` (`AiAgentOpenAi`), prefixing every logcat tag
189208

190209
The pure units carry the logic that would otherwise only fail on a device; they
191-
are covered by 177 JVM tests.
210+
are covered by 245 JVM tests.
192211

193212
## License
194213

0 commit comments

Comments
 (0)