structured_outputs.go 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. package sample
  2. import "github.com/ollama/ollama/model"
  3. type StructuredOutput struct {
  4. schema *Schema
  5. stateToNodeMap map[JSONState]*PDANode
  6. }
  7. func BuildStructuredOutputGraph(schema *Schema, proc model.TextProcessor) *StructuredOutput {
  8. _, stateToNodeMap, err := BuildGraph(proc)
  9. if err != nil {
  10. panic(err)
  11. }
  12. return &StructuredOutput{
  13. schema: schema,
  14. stateToNodeMap: stateToNodeMap,
  15. }
  16. }
  17. func (so *StructuredOutput) schemaToGraph(proc model.TextProcessor) *PDANode {
  18. schemaType := so.schema.EffectiveType()
  19. switch schemaType {
  20. case "object":
  21. // each prop is a key
  22. // prevState := StateInObjectKey
  23. for _, prop := range so.schema.Properties {
  24. // name of key
  25. name := prop.Name
  26. prevState := StateInObjectKey
  27. for i, r := range name {
  28. newState := JSONState(int(StateInObjectKey) + i + 1) // Create new unique state for each rune
  29. // Create new node for this state if it doesn't exist
  30. if _, exists := so.stateToNodeMap[newState]; !exists {
  31. so.stateToNodeMap[newState] = &PDANode{
  32. State: newState,
  33. TransitionEdges: make(map[rune]*PDANode),
  34. MaskTokenIDToNode: make(map[int32]JSONState),
  35. }
  36. }
  37. // Connect previous state to this state via the rune
  38. so.stateToNodeMap[prevState].TransitionEdges[r] = so.stateToNodeMap[newState]
  39. prevState = newState
  40. }
  41. // type of value
  42. // propType := prop.Type
  43. }
  44. }
  45. return nil
  46. }