Skip to content

Commit f1bd2a2

Browse files
committed
OpenAI responses API - examples with tools and MCP servers
1 parent c155199 commit f1bd2a2

File tree

4 files changed

+145
-16
lines changed

4 files changed

+145
-16
lines changed

openai-examples/src/main/scala/io/cequence/openaiscala/examples/responsesapi/CreateModelResponseWithFunctions.scala

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
package io.cequence.openaiscala.examples.responsesapi
22

33
import scala.concurrent.Future
4-
import io.cequence.openaiscala.domain.responsesapi.{Inputs, CreateModelResponseSettings}
4+
import io.cequence.openaiscala.domain.responsesapi.{CreateModelResponseSettings, Inputs}
55
import io.cequence.openaiscala.examples.Example
66
import io.cequence.openaiscala.domain.ModelId
7-
import io.cequence.openaiscala.domain.responsesapi.tools.FunctionTool
7+
import io.cequence.openaiscala.domain.responsesapi.tools.{FunctionTool, Tool, ToolChoice}
88
import io.cequence.openaiscala.domain.JsonSchema
9-
import io.cequence.openaiscala.domain.responsesapi.tools.ToolChoice
109

1110
object CreateModelResponseWithFunctions extends Example {
1211

@@ -17,7 +16,7 @@ object CreateModelResponseWithFunctions extends Example {
1716
settings = CreateModelResponseSettings(
1817
model = ModelId.gpt_5_mini,
1918
tools = Seq(
20-
FunctionTool(
19+
Tool.function(
2120
name = "get_current_weather",
2221
parameters = JsonSchema.Object(
2322
properties = Map(
@@ -50,7 +49,7 @@ object CreateModelResponseWithFunctions extends Example {
5049
|Status: ${functionCall.status}""".stripMargin
5150
)
5251

53-
val toolsUsed = response.tools.map(_.typeString)
52+
val toolsUsed = response.tools.map(_.`type`)
5453

5554
println(s"${toolsUsed.size} tools used: ${toolsUsed.mkString(", ")}")
5655
}

openai-examples/src/main/scala/io/cequence/openaiscala/examples/responsesapi/CreateModelResponseWithImageGeneration.scala

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
11
package io.cequence.openaiscala.examples.responsesapi
22

33
import scala.concurrent.Future
4-
import io.cequence.openaiscala.domain.responsesapi.{Inputs, CreateModelResponseSettings}
4+
import io.cequence.openaiscala.domain.responsesapi.{CreateModelResponseSettings, Inputs}
55
import io.cequence.openaiscala.examples.Example
66
import io.cequence.openaiscala.domain.ModelId
7-
import io.cequence.openaiscala.domain.responsesapi.tools.{
8-
ImageGenerationTool,
9-
ImageGenerationBackground
10-
}
7+
import io.cequence.openaiscala.domain.responsesapi.tools.{ImageGenerationBackground, ImageGenerationTool, Tool}
118

129
object CreateModelResponseWithImageGeneration extends Example {
1310

@@ -16,9 +13,9 @@ object CreateModelResponseWithImageGeneration extends Example {
1613
.createModelResponse(
1714
Inputs.Text("Generate an image of a sunset over the ocean with a sailboat."),
1815
settings = CreateModelResponseSettings(
19-
model = ModelId.gpt_5_nano,
16+
model = ModelId.gpt_5_mini,
2017
tools = Seq(
21-
ImageGenerationTool(
18+
Tool.imageGeneration(
2219
background = Some(ImageGenerationBackground.auto),
2320
model = None,
2421
quality = Some("high"),
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
package io.cequence.openaiscala.examples.responsesapi
2+
3+
import io.cequence.openaiscala.domain.ModelId
4+
import io.cequence.openaiscala.domain.responsesapi.tools.Tool
5+
import io.cequence.openaiscala.domain.responsesapi.tools.mcp.{
6+
MCPApprovalRequest,
7+
MCPApprovalResponse,
8+
MCPRequireApproval,
9+
MCPTool
10+
}
11+
import io.cequence.openaiscala.domain.responsesapi.{CreateModelResponseSettings, Inputs}
12+
import io.cequence.openaiscala.examples.Example
13+
14+
import scala.concurrent.Future
15+
16+
object CreateModelResponseWithMCPTool extends Example {
17+
18+
private val model = ModelId.gpt_5_mini
19+
20+
// Example 1: DeepWiki MCP Tool
21+
private val deepwikiMcpTool = Tool.mcp(
22+
serverLabel = "deepwiki",
23+
serverUrl = Some("https://mcp.deepwiki.com/sse"),
24+
requireApproval = Some(MCPRequireApproval.Setting.Always)
25+
)
26+
27+
// Example 2: Semgrep MCP Tool
28+
private val semgrepMcpTool = Tool.mcp(
29+
serverLabel = "semgrep",
30+
serverUrl = Some("https://mcp.semgrep.ai/mcp"),
31+
requireApproval = Some(MCPRequireApproval.Setting.Never)
32+
)
33+
34+
override def run: Future[Unit] = {
35+
for {
36+
// Example 1: Using DeepWiki MCP Server (with approval flow)
37+
response1Initial <- {
38+
println("=" * 60)
39+
println("Example 1: Using DeepWiki MCP Server (with approval)")
40+
println("=" * 60)
41+
42+
service.createModelResponse(
43+
Inputs.Text(
44+
"Search for information about Scala programming language in scala/scala."
45+
),
46+
settings = CreateModelResponseSettings(
47+
model = model,
48+
tools = Seq(deepwikiMcpTool)
49+
)
50+
)
51+
}
52+
53+
// Check for approval requests in the output
54+
approvalRequests = response1Initial.output.collect { case req: MCPApprovalRequest =>
55+
req
56+
}
57+
58+
_ = {
59+
if (approvalRequests.nonEmpty) {
60+
println(s"Received ${approvalRequests.length} approval request(s)")
61+
approvalRequests.foreach { req =>
62+
println(s" - Tool: ${req.name} on server: ${req.serverLabel}")
63+
println(s" Request ID: ${req.id}")
64+
println(s" Arguments: ${req.arguments}")
65+
}
66+
}
67+
}
68+
69+
// Submit approval responses if needed
70+
response1Final <- {
71+
if (approvalRequests.nonEmpty) {
72+
println("Submitting approval responses...")
73+
74+
val approvalResponses = approvalRequests.map { req =>
75+
MCPApprovalResponse(
76+
approvalRequestId = req.id,
77+
approve = true
78+
// Note: 'reason' can only be provided when approve=false
79+
)
80+
}
81+
82+
// Submit approval responses by continuing the conversation
83+
// IMPORTANT: Set previousResponseId to link the approval responses to the original request
84+
service.createModelResponse(
85+
Inputs.Items(approvalResponses: _*),
86+
settings = CreateModelResponseSettings(
87+
model = model,
88+
previousResponseId =
89+
Some(response1Initial.id), // Continue from the request that asked for approval
90+
tools = Seq(deepwikiMcpTool)
91+
)
92+
)
93+
} else {
94+
Future.successful(response1Initial)
95+
}
96+
}
97+
98+
_ = {
99+
response1Final.output.foreach { output =>
100+
println(output)
101+
}
102+
}
103+
104+
// Example 2: Using Semgrep MCP Server (no approval required)
105+
response2 <- {
106+
println("=" * 60)
107+
println("Example 2: Using Semgrep MCP Server")
108+
println("=" * 60)
109+
110+
service.createModelResponse(
111+
Inputs.Text(
112+
"Analyze this code for security vulnerabilities: def unsafe(input: String) = s\"SELECT * FROM users WHERE name = '$input'\""
113+
),
114+
settings = CreateModelResponseSettings(
115+
model = model,
116+
tools = Seq(semgrepMcpTool)
117+
)
118+
)
119+
}
120+
121+
} yield {
122+
response2.output.foreach { output =>
123+
println(output)
124+
}
125+
126+
println("=" * 60)
127+
println("Example Summary:")
128+
println(" - Example 1 (DeepWiki): Demonstrated approval flow")
129+
println(" - Example 2 (Semgrep): No approval required")
130+
println("=" * 60)
131+
}
132+
}
133+
}

openai-examples/src/main/scala/io/cequence/openaiscala/examples/responsesapi/CreateModelResponseWithWebSearch.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
package io.cequence.openaiscala.examples.responsesapi
22

33
import scala.concurrent.Future
4-
import io.cequence.openaiscala.domain.responsesapi.{Inputs, CreateModelResponseSettings}
4+
import io.cequence.openaiscala.domain.responsesapi.{CreateModelResponseSettings, Inputs}
55
import io.cequence.openaiscala.examples.Example
66
import io.cequence.openaiscala.domain.ModelId
77
import io.cequence.openaiscala.domain.responsesapi.OutputMessageContent.OutputText
8-
import io.cequence.openaiscala.domain.responsesapi.tools.WebSearchTool
8+
import io.cequence.openaiscala.domain.responsesapi.tools.{Tool, WebSearchTool}
99
import io.cequence.openaiscala.domain.responsesapi.Annotation
1010

1111
object CreateModelResponseWithWebSearch extends Example {
@@ -15,8 +15,8 @@ object CreateModelResponseWithWebSearch extends Example {
1515
.createModelResponse(
1616
Inputs.Text("What was a positive news story from today?"),
1717
settings = CreateModelResponseSettings(
18-
model = ModelId.gpt_4_1,
19-
tools = Seq(WebSearchTool())
18+
model = ModelId.gpt_5_mini,
19+
tools = Seq(Tool.webSearch())
2020
)
2121
)
2222
.map { response =>

0 commit comments

Comments
 (0)