Files
zeekayandHanzo Dev 88762272c3 refactor(module): declare own import path github.com/hanzoai/go-openai
The fork kept the upstream module path (module github.com/sashabaranov/
go-openai), so every consumer could only reach it through a
"replace github.com/sashabaranov/go-openai => github.com/hanzoai/go-openai"
directive — and Go replace directives do NOT propagate to consumers, so each
downstream repo had to copy the same replace or fail to compile against
fork-only fields (e.g. ReasoningContent). That is the opposite of one-and-
only-one-way.

Declare the fork's OWN module path so it can be required directly and inherited
transitively. Package name stays 'openai' (import identifier unchanged); only
the module path + internal self-imports (/internal, /jsonschema) are renamed.
Upstream issue-URL comments are left intact as attribution. Builds + vets clean.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-17 21:55:51 -07:00

238 lines
5.7 KiB
Go

package openai_test
import (
"context"
openai "github.com/hanzoai/go-openai"
"github.com/hanzoai/go-openai/internal/test/checks"
"encoding/json"
"fmt"
"net/http"
"testing"
)
// TestAssistant Tests the assistant endpoint of the API using the mocked server.
func TestRun(t *testing.T) {
assistantID := "asst_abc123"
threadID := "thread_abc123"
runID := "run_abc123"
stepID := "step_abc123"
limit := 20
order := "desc"
after := "asst_abc122"
before := "asst_abc124"
client, server, teardown := setupOpenAITestServer()
defer teardown()
server.RegisterHandler(
"/v1/threads/"+threadID+"/runs/"+runID+"/steps/"+stepID,
func(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodGet {
resBytes, _ := json.Marshal(openai.RunStep{
ID: runID,
Object: "run",
CreatedAt: 1234567890,
Status: openai.RunStepStatusCompleted,
})
fmt.Fprintln(w, string(resBytes))
}
},
)
server.RegisterHandler(
"/v1/threads/"+threadID+"/runs/"+runID+"/steps",
func(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodGet {
resBytes, _ := json.Marshal(openai.RunStepList{
RunSteps: []openai.RunStep{
{
ID: runID,
Object: "run",
CreatedAt: 1234567890,
Status: openai.RunStepStatusCompleted,
},
},
})
fmt.Fprintln(w, string(resBytes))
}
},
)
server.RegisterHandler(
"/v1/threads/"+threadID+"/runs/"+runID+"/cancel",
func(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodPost {
resBytes, _ := json.Marshal(openai.Run{
ID: runID,
Object: "run",
CreatedAt: 1234567890,
Status: openai.RunStatusCancelling,
})
fmt.Fprintln(w, string(resBytes))
}
},
)
server.RegisterHandler(
"/v1/threads/"+threadID+"/runs/"+runID+"/submit_tool_outputs",
func(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodPost {
resBytes, _ := json.Marshal(openai.Run{
ID: runID,
Object: "run",
CreatedAt: 1234567890,
Status: openai.RunStatusCancelling,
})
fmt.Fprintln(w, string(resBytes))
}
},
)
server.RegisterHandler(
"/v1/threads/"+threadID+"/runs/"+runID,
func(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodGet {
resBytes, _ := json.Marshal(openai.Run{
ID: runID,
Object: "run",
CreatedAt: 1234567890,
Status: openai.RunStatusQueued,
})
fmt.Fprintln(w, string(resBytes))
} else if r.Method == http.MethodPost {
var request openai.RunModifyRequest
err := json.NewDecoder(r.Body).Decode(&request)
checks.NoError(t, err, "Decode error")
resBytes, _ := json.Marshal(openai.Run{
ID: runID,
Object: "run",
CreatedAt: 1234567890,
Status: openai.RunStatusQueued,
Metadata: request.Metadata,
})
fmt.Fprintln(w, string(resBytes))
}
},
)
server.RegisterHandler(
"/v1/threads/"+threadID+"/runs",
func(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodPost {
var request openai.RunRequest
err := json.NewDecoder(r.Body).Decode(&request)
checks.NoError(t, err, "Decode error")
resBytes, _ := json.Marshal(openai.Run{
ID: runID,
Object: "run",
CreatedAt: 1234567890,
Status: openai.RunStatusQueued,
})
fmt.Fprintln(w, string(resBytes))
} else if r.Method == http.MethodGet {
resBytes, _ := json.Marshal(openai.RunList{
Runs: []openai.Run{
{
ID: runID,
Object: "run",
CreatedAt: 1234567890,
Status: openai.RunStatusQueued,
},
},
})
fmt.Fprintln(w, string(resBytes))
}
},
)
server.RegisterHandler(
"/v1/threads/runs",
func(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodPost {
var request openai.CreateThreadAndRunRequest
err := json.NewDecoder(r.Body).Decode(&request)
checks.NoError(t, err, "Decode error")
resBytes, _ := json.Marshal(openai.Run{
ID: runID,
Object: "run",
CreatedAt: 1234567890,
Status: openai.RunStatusQueued,
})
fmt.Fprintln(w, string(resBytes))
}
},
)
ctx := context.Background()
_, err := client.CreateRun(ctx, threadID, openai.RunRequest{
AssistantID: assistantID,
})
checks.NoError(t, err, "CreateRun error")
_, err = client.RetrieveRun(ctx, threadID, runID)
checks.NoError(t, err, "RetrieveRun error")
_, err = client.ModifyRun(ctx, threadID, runID, openai.RunModifyRequest{
Metadata: map[string]any{
"key": "value",
},
})
checks.NoError(t, err, "ModifyRun error")
_, err = client.ListRuns(
ctx,
threadID,
openai.Pagination{
Limit: &limit,
Order: &order,
After: &after,
Before: &before,
},
)
checks.NoError(t, err, "ListRuns error")
_, err = client.SubmitToolOutputs(ctx, threadID, runID,
openai.SubmitToolOutputsRequest{})
checks.NoError(t, err, "SubmitToolOutputs error")
_, err = client.CancelRun(ctx, threadID, runID)
checks.NoError(t, err, "CancelRun error")
_, err = client.CreateThreadAndRun(ctx, openai.CreateThreadAndRunRequest{
RunRequest: openai.RunRequest{
AssistantID: assistantID,
},
Thread: openai.ThreadRequest{
Messages: []openai.ThreadMessage{
{
Role: openai.ThreadMessageRoleUser,
Content: "Hello, World!",
},
},
},
})
checks.NoError(t, err, "CreateThreadAndRun error")
_, err = client.RetrieveRunStep(ctx, threadID, runID, stepID)
checks.NoError(t, err, "RetrieveRunStep error")
_, err = client.ListRunSteps(
ctx,
threadID,
runID,
openai.Pagination{
Limit: &limit,
Order: &order,
After: &after,
Before: &before,
},
)
checks.NoError(t, err, "ListRunSteps error")
}