Skip to content

Commit 79fc1f4

Browse files
committed
fix(lint): resolve goconst issues for golangci-lint v2.12.2
- Extract string constants in stream/handler.go, guardrail/chain.go, and jsonschema/response_format.go for repeated map keys - Exclude examples/ from goconst (demo code, not library)
1 parent 5e3d38c commit 79fc1f4

4 files changed

Lines changed: 79 additions & 58 deletions

File tree

.golangci.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ linters:
1818
- staticcheck
1919
- unused
2020

21+
exclusions:
22+
rules:
23+
- linters: [goconst]
24+
path: examples/
25+
2126
settings:
2227
goconst:
2328
min-occurrences: 5

guardrail/chain.go

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@ const (
1919
StopOnFirstPass
2020
)
2121

22+
// Metadata map keys used across chain results.
23+
const (
24+
keyStrategy = "strategy"
25+
keyResults = "results"
26+
)
27+
2228
// String returns the string representation of the Strategy.
2329
func (s Strategy) String() string {
2430
switch s {
@@ -131,8 +137,8 @@ func (c *Chain) executeSequential(ctx context.Context, input string) (*Result, e
131137
Message: fmt.Sprintf("guardrail %s failed: %s", g.Name, result.Message),
132138
Metadata: map[string]any{
133139
"failed_guardrail": g.Name,
134-
"strategy": "Sequential",
135-
"results": results,
140+
keyStrategy: "Sequential",
141+
keyResults: results,
136142
},
137143
}, nil
138144
}
@@ -144,8 +150,8 @@ func (c *Chain) executeSequential(ctx context.Context, input string) (*Result, e
144150
TripwireTriggered: false,
145151
Message: fmt.Sprintf("all %d guardrails passed", len(c.guardrails)),
146152
Metadata: map[string]any{
147-
"strategy": "Sequential",
148-
"results": results,
153+
keyStrategy: "Sequential",
154+
keyResults: results,
149155
},
150156
}, nil
151157
}
@@ -211,10 +217,10 @@ func (c *Chain) executeParallel(ctx context.Context, input string) (*Result, err
211217
TripwireTriggered: hasTripwire,
212218
Message: fmt.Sprintf("%d/%d guardrails failed: %v", len(failures), len(c.guardrails), failures),
213219
Metadata: map[string]any{
214-
"strategy": "Parallel",
220+
keyStrategy: "Parallel",
215221
"failed_count": len(failures),
216222
"failed_guardrails": failures,
217-
"results": results,
223+
keyResults: results,
218224
},
219225
}, nil
220226
}
@@ -224,8 +230,8 @@ func (c *Chain) executeParallel(ctx context.Context, input string) (*Result, err
224230
TripwireTriggered: false,
225231
Message: fmt.Sprintf("all %d guardrails passed", len(c.guardrails)),
226232
Metadata: map[string]any{
227-
"strategy": "Parallel",
228-
"results": results,
233+
keyStrategy: "Parallel",
234+
keyResults: results,
229235
},
230236
}, nil
231237
}
@@ -249,9 +255,9 @@ func (c *Chain) executeStopOnFirstPass(ctx context.Context, input string) (*Resu
249255
TripwireTriggered: false,
250256
Message: fmt.Sprintf("guardrail %s passed", g.Name),
251257
Metadata: map[string]any{
252-
"strategy": "StopOnFirstPass",
258+
keyStrategy: "StopOnFirstPass",
253259
"passed_guardrail": g.Name,
254-
"results": results,
260+
keyResults: results,
255261
},
256262
}, nil
257263
}
@@ -263,8 +269,8 @@ func (c *Chain) executeStopOnFirstPass(ctx context.Context, input string) (*Resu
263269
TripwireTriggered: false,
264270
Message: fmt.Sprintf("all %d guardrails failed", len(c.guardrails)),
265271
Metadata: map[string]any{
266-
"strategy": "StopOnFirstPass",
267-
"results": results,
272+
keyStrategy: "StopOnFirstPass",
273+
keyResults: results,
268274
},
269275
}, nil
270276
}

jsonschema/response_format.go

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import (
44
"fmt"
55
)
66

7+
const typeJSONSchema = "json_schema"
8+
79
// ResponseFormat defines how the LLM should structure its response.
810
type ResponseFormat struct {
911
// Type is either "text" or "json_schema"
@@ -40,7 +42,7 @@ func Text() *ResponseFormat {
4042
// JSONSchema creates a structured JSON response format.
4143
func JSONSchema(name string, schema *Schema) *ResponseFormat {
4244
return &ResponseFormat{
43-
Type: "json_schema",
45+
Type: typeJSONSchema,
4446
JSONSchema: &JSONSchemaFormat{
4547
Name: name,
4648
Schema: schema,
@@ -67,11 +69,11 @@ func (r *ResponseFormat) WithStrict(strict bool) *ResponseFormat {
6769

6870
// Validate checks if the response format is valid.
6971
func (r *ResponseFormat) Validate() error {
70-
if r.Type != "text" && r.Type != "json_schema" {
72+
if r.Type != "text" && r.Type != typeJSONSchema {
7173
return fmt.Errorf("invalid response format type: %s (must be 'text' or 'json_schema')", r.Type)
7274
}
7375

74-
if r.Type == "json_schema" {
76+
if r.Type == typeJSONSchema {
7577
if r.JSONSchema == nil {
7678
return fmt.Errorf("json_schema type requires JSONSchema to be set")
7779
}
@@ -108,16 +110,16 @@ func (r *ResponseFormat) ToOpenAIParam() (any, error) {
108110
}
109111

110112
result := map[string]any{
111-
"type": "json_schema",
112-
"json_schema": map[string]any{
113+
"type": typeJSONSchema,
114+
typeJSONSchema: map[string]any{
113115
"name": r.JSONSchema.Name,
114116
"schema": schemaMap,
115117
"strict": r.JSONSchema.Strict,
116118
},
117119
}
118120

119121
if r.JSONSchema.Description != "" {
120-
result["json_schema"].(map[string]any)["description"] = r.JSONSchema.Description
122+
result[typeJSONSchema].(map[string]any)["description"] = r.JSONSchema.Description
121123
}
122124

123125
return result, nil

stream/handler.go

Lines changed: 48 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@ import (
44
"github.com/openai/openai-go/v3"
55
)
66

7+
const (
8+
keyOutputIndex = "output_index"
9+
keyContentIndex = "content_index"
10+
keyType = "type"
11+
keyItem = "item"
12+
keyRefusal = "refusal"
13+
)
14+
715
// Handler processes streaming chat completion chunks and converts them into
816
// structured stream events. It maintains state across chunks to reconstruct
917
// complete messages, function calls, and reasoning content.
@@ -154,9 +162,9 @@ func (h *Handler) processTextContent(content string) []Event {
154162
events = append(events, &RawResponseEvent{
155163
Type: "response.output_item.added",
156164
Data: map[string]any{
157-
"output_index": h.state.reasoningOutputOffset(),
158-
"item": map[string]any{
159-
"type": "message",
165+
keyOutputIndex: h.state.reasoningOutputOffset(),
166+
keyItem: map[string]any{
167+
keyType: "message",
160168
"role": "assistant",
161169
"content": []any{},
162170
"status": "in_progress",
@@ -169,11 +177,11 @@ func (h *Handler) processTextContent(content string) []Event {
169177
events = append(events, &RawResponseEvent{
170178
Type: "response.content_part.added",
171179
Data: map[string]any{
172-
"content_index": h.state.textContentIndex.index,
173-
"output_index": h.state.reasoningOutputOffset(),
180+
keyContentIndex: h.state.textContentIndex.index,
181+
keyOutputIndex: h.state.reasoningOutputOffset(),
174182
"part": map[string]any{
175-
"type": "output_text",
176-
"text": "",
183+
keyType: "output_text",
184+
"text": "",
177185
},
178186
},
179187
SequenceNumber: h.seqNum.Next(),
@@ -184,8 +192,8 @@ func (h *Handler) processTextContent(content string) []Event {
184192
events = append(events, &RawResponseEvent{
185193
Type: "response.output_text.delta",
186194
Data: map[string]any{
187-
"content_index": h.state.textContentIndex.index,
188-
"output_index": h.state.reasoningOutputOffset(),
195+
keyContentIndex: h.state.textContentIndex.index,
196+
keyOutputIndex: h.state.reasoningOutputOffset(),
189197
"delta": content,
190198
},
191199
SequenceNumber: h.seqNum.Next(),
@@ -220,9 +228,9 @@ func (h *Handler) processRefusal(refusal string) []Event {
220228
events = append(events, &RawResponseEvent{
221229
Type: "response.output_item.added",
222230
Data: map[string]any{
223-
"output_index": h.state.reasoningOutputOffset(),
224-
"item": map[string]any{
225-
"type": "message",
231+
keyOutputIndex: h.state.reasoningOutputOffset(),
232+
keyItem: map[string]any{
233+
keyType: "message",
226234
"role": "assistant",
227235
"content": []any{},
228236
"status": "in_progress",
@@ -234,11 +242,11 @@ func (h *Handler) processRefusal(refusal string) []Event {
234242
events = append(events, &RawResponseEvent{
235243
Type: "response.content_part.added",
236244
Data: map[string]any{
237-
"content_index": h.state.refusalContentIndex.index,
238-
"output_index": h.state.reasoningOutputOffset(),
245+
keyContentIndex: h.state.refusalContentIndex.index,
246+
keyOutputIndex: h.state.reasoningOutputOffset(),
239247
"part": map[string]any{
240-
"type": "refusal",
241-
"refusal": "",
248+
keyType: keyRefusal,
249+
keyRefusal: "",
242250
},
243251
},
244252
SequenceNumber: h.seqNum.Next(),
@@ -249,8 +257,8 @@ func (h *Handler) processRefusal(refusal string) []Event {
249257
events = append(events, &RawResponseEvent{
250258
Type: "response.refusal.delta",
251259
Data: map[string]any{
252-
"content_index": h.state.refusalContentIndex.index,
253-
"output_index": h.state.reasoningOutputOffset(),
260+
keyContentIndex: h.state.refusalContentIndex.index,
261+
keyOutputIndex: h.state.reasoningOutputOffset(),
254262
"delta": refusal,
255263
},
256264
SequenceNumber: h.seqNum.Next(),
@@ -322,9 +330,9 @@ func (h *Handler) processToolCalls(toolCalls []openai.ChatCompletionChunkChoiceD
322330
events = append(events, &RawResponseEvent{
323331
Type: "response.output_item.added",
324332
Data: map[string]any{
325-
"output_index": outputIndex,
326-
"item": map[string]any{
327-
"type": "function_call",
333+
keyOutputIndex: outputIndex,
334+
keyItem: map[string]any{
335+
keyType: "function_call",
328336
"call_id": builder.callID,
329337
"name": builder.name,
330338
"arguments": "",
@@ -340,7 +348,7 @@ func (h *Handler) processToolCalls(toolCalls []openai.ChatCompletionChunkChoiceD
340348
events = append(events, &RawResponseEvent{
341349
Type: "response.function_call_arguments.delta",
342350
Data: map[string]any{
343-
"output_index": outputIndex,
351+
keyOutputIndex: outputIndex,
344352
"delta": tc.Function.Arguments,
345353
},
346354
SequenceNumber: h.seqNum.Next(),
@@ -360,11 +368,11 @@ func (h *Handler) Finalize() []Event {
360368
events = append(events, &RawResponseEvent{
361369
Type: "response.content_part.done",
362370
Data: map[string]any{
363-
"content_index": h.state.textContentIndex.index,
364-
"output_index": h.state.reasoningOutputOffset(),
371+
keyContentIndex: h.state.textContentIndex.index,
372+
keyOutputIndex: h.state.reasoningOutputOffset(),
365373
"part": map[string]any{
366-
"type": "output_text",
367-
"text": h.state.textContentIndex.text,
374+
keyType: "output_text",
375+
"text": h.state.textContentIndex.text,
368376
},
369377
},
370378
SequenceNumber: h.seqNum.Next(),
@@ -376,11 +384,11 @@ func (h *Handler) Finalize() []Event {
376384
events = append(events, &RawResponseEvent{
377385
Type: "response.content_part.done",
378386
Data: map[string]any{
379-
"content_index": h.state.refusalContentIndex.index,
380-
"output_index": h.state.reasoningOutputOffset(),
387+
keyContentIndex: h.state.refusalContentIndex.index,
388+
keyOutputIndex: h.state.reasoningOutputOffset(),
381389
"part": map[string]any{
382-
"type": "refusal",
383-
"refusal": h.state.refusalContentIndex.refusal,
390+
keyType: keyRefusal,
391+
keyRefusal: h.state.refusalContentIndex.refusal,
384392
},
385393
},
386394
SequenceNumber: h.seqNum.Next(),
@@ -394,9 +402,9 @@ func (h *Handler) Finalize() []Event {
394402
events = append(events, &RawResponseEvent{
395403
Type: "response.output_item.done",
396404
Data: map[string]any{
397-
"output_index": outputIndex,
398-
"item": map[string]any{
399-
"type": "function_call",
405+
keyOutputIndex: outputIndex,
406+
keyItem: map[string]any{
407+
keyType: "function_call",
400408
"call_id": builder.callID,
401409
"name": builder.name,
402410
"arguments": builder.arguments,
@@ -412,23 +420,23 @@ func (h *Handler) Finalize() []Event {
412420
content := make([]map[string]any, 0)
413421
if h.state.textContentIndex != nil {
414422
content = append(content, map[string]any{
415-
"type": "output_text",
416-
"text": h.state.textContentIndex.text,
423+
keyType: "output_text",
424+
"text": h.state.textContentIndex.text,
417425
})
418426
}
419427
if h.state.refusalContentIndex != nil {
420428
content = append(content, map[string]any{
421-
"type": "refusal",
422-
"refusal": h.state.refusalContentIndex.refusal,
429+
keyType: keyRefusal,
430+
keyRefusal: h.state.refusalContentIndex.refusal,
423431
})
424432
}
425433

426434
events = append(events, &RawResponseEvent{
427435
Type: "response.output_item.done",
428436
Data: map[string]any{
429-
"output_index": h.state.reasoningOutputOffset(),
430-
"item": map[string]any{
431-
"type": "message",
437+
keyOutputIndex: h.state.reasoningOutputOffset(),
438+
keyItem: map[string]any{
439+
keyType: "message",
432440
"role": "assistant",
433441
"content": content,
434442
"status": "completed",

0 commit comments

Comments
 (0)