- internal/ai/types.go: IntakeRequest, IntakeResult, TierConfig, AIConfig domain types - internal/ai/client.go: AIClient interface + TierClient (go-openai, BaseURL tier-routing) - internal/ai/mock.go: MockAIClient test double with HighConfidenceResult/LowConfidenceResult fixtures - internal/ai/prompts/intake.go: BuildIntakePrompt() JSON-extraction prompt template - internal/config/config.go: Config.AI AIConfig field, tier defaults, env bindings, ai_config.json merge - ai_config.json: template config with placeholder Tier2 API key - .gitignore: add ai_config.local.json pattern for real keys (T-02-01 mitigation) - All tests pass: TestMockAIClient, TestMockAIClientError, TestTierClientConstruction, TestAIConfigDefaults
21 lines
1.2 KiB
Go
21 lines
1.2 KiB
Go
package prompts
|
|
|
|
import "fmt"
|
|
|
|
// BuildIntakePrompt returns the vision prompt instructing the model to return
|
|
// structured JSON for hardware analysis. photoCount is 1-3.
|
|
func BuildIntakePrompt(photoCount int) string {
|
|
return fmt.Sprintf(`You are a hardware inventory assistant. Analyze the %d hardware photo(s) provided and return ONLY valid JSON matching this exact schema. Do not include markdown, code fences, or explanations — return only the raw JSON object.
|
|
|
|
{
|
|
"serial_number": "<string — exact serial number visible on label, or empty string if not visible>",
|
|
"model": "<string — product model name>",
|
|
"manufacturer": "<string — manufacturer/brand name>",
|
|
"category": "<one of: compute, networking, storage, cable, peripheral, component, unknown>",
|
|
"specs": {"<spec_key>": "<spec_value>"},
|
|
"suggested_tags": ["<tag1>", "<tag2>"],
|
|
"ai_notes": "<free-form observations about condition, notable features, or ambiguities>",
|
|
"confidence": <float between 0.0 and 1.0 — your confidence in the identification>,
|
|
"confidence_note": "<reason why confidence is below 0.75, or empty string if confidence >= 0.75>"
|
|
}`, photoCount)
|
|
}
|