Created
September 23, 2025 00:20
-
-
Save colindotfun/acb4e752291b2bb87cd6e968363a5112 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import type { | |
| ResponseInputItem, | |
| ResponseItem, | |
| Tool, | |
| } from "openai/resources/responses/responses"; | |
| import { orTrace } from "@examples/client"; | |
| import { openaiClient } from "@examples/openai-client"; | |
| import { logConversation } from "@examples/openai/log-conversation"; | |
| import { generateRandomNumber, randomNumberTool } from "@examples/tools"; | |
| // Register our custom function tool | |
| const tools: Tool[] = [randomNumberTool]; | |
| // Running input list for the conversation | |
| const input: ResponseInputItem[] = [ | |
| { | |
| role: "user", | |
| type: "message", | |
| content: | |
| "Keep calling the generate_random_number tool until it returns a value < 10. Explain your reasoning briefly each step.", | |
| }, | |
| ]; | |
| let found = false; | |
| let latestBelowTen: number | null = null; | |
| let round = 0; | |
| const maxRounds = 50; | |
| // Simple local state for trace parenting (no globalThis) | |
| let latestMessageBlockId: string | undefined; | |
| let lastToolCallBlockId: string | undefined; | |
| while (round < maxRounds && !found) { | |
| if (round === 0) { | |
| const first = input[0] as any; | |
| if (first?.type === "message" && first.role === "user") { | |
| const userBlock = await orTrace.logMessage({ | |
| role: "user", | |
| content: String(first.content ?? ""), | |
| raw: first, | |
| }); | |
| // keep latest user/assistant message id to parent tool calls | |
| latestMessageBlockId = userBlock.id; | |
| } | |
| } | |
| const response = await openaiClient.responses.create({ | |
| model: "gpt-5", | |
| tools, | |
| input, | |
| reasoning: { effort: "high", summary: "detailed" }, | |
| parallel_tool_calls: false, | |
| }); | |
| const outputItems = response.output as ResponseItem[]; | |
| for (const item of outputItems) { | |
| // Keep full transcript for subsequent calls | |
| input.push(item as ResponseInputItem); | |
| if ( | |
| (item as any).type === "function_call" && | |
| (item as any).name === "generate_random_number" | |
| ) { | |
| const toolCallBlock = await orTrace.logAct({ | |
| parent_block_id: latestMessageBlockId!, | |
| name: (item as any).name, | |
| arguments: (item as any).arguments, | |
| call_id: (item as any).call_id, | |
| raw: item as any, | |
| }); | |
| lastToolCallBlockId = toolCallBlock.id; | |
| // Execute local tool | |
| const result = await generateRandomNumber(); | |
| // Feed the tool result back to the model | |
| input.push({ | |
| type: "function_call_output", | |
| call_id: (item as any).call_id, | |
| output: JSON.stringify(result), | |
| } as ResponseInputItem); | |
| await orTrace.logObserve({ | |
| parent_block_id: lastToolCallBlockId!, | |
| output: result as any, | |
| call_id: (item as any).call_id, | |
| extra: { reward: result.value < 10 ? 1 : 0 }, | |
| }); | |
| // Console visibility for the sample | |
| // eslint-disable-next-line no-console | |
| console.log("generate_random_number ->", result.value); | |
| if (result.value < 10) { | |
| lastToolCallBlockId = undefined; | |
| found = true; | |
| latestBelowTen = result.value; | |
| break; | |
| } else { | |
| lastToolCallBlockId = undefined; | |
| } | |
| } else if ((item as any).type === "reasoning") { | |
| // Log reasoning steps as "think" blocks | |
| const reasoningContent = (item as any).summary || []; | |
| if (reasoningContent.length > 0 && latestMessageBlockId) { | |
| await orTrace.logThink({ | |
| parent_block_id: latestMessageBlockId, | |
| payload: { | |
| text: reasoningContent.map((r: any) => r.text).join("\n\n"), | |
| reasoning_summary: reasoningContent, | |
| reasoning_id: (item as any).id, | |
| }, | |
| raw: item as any, | |
| }); | |
| console.log("🧠 Reasoning:", reasoningContent); | |
| } else { | |
| console.log("🧠 Empty reasoning step:", (item as any).id); | |
| } | |
| } else if ((item as any).type === "message") { | |
| const role = (item as any).role ?? "assistant"; | |
| const parts = (item as any).content; | |
| const text = | |
| typeof parts === "string" | |
| ? parts | |
| : Array.isArray(parts) | |
| ? String( | |
| parts.find((p: any) => p?.type === "output_text")?.text ?? "" | |
| ) | |
| : ""; | |
| if (role === "assistant") { | |
| const assistantBlock = await orTrace.logMessage({ | |
| role: "assistant", | |
| content: text, | |
| raw: item as any, | |
| }); | |
| latestMessageBlockId = assistantBlock.id; | |
| lastToolCallBlockId = undefined; | |
| } | |
| } | |
| } | |
| round += 1; | |
| } | |
| if (found) { | |
| // eslint-disable-next-line no-console | |
| console.log("Success: got value < 10:", latestBelowTen); | |
| } else { | |
| // eslint-disable-next-line no-console | |
| console.log("Stopped without getting a value < 10."); | |
| } | |
| logConversation({ | |
| conversation: input, | |
| heading: "Conversation transcript:", | |
| }); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment