Class: TurnKit::OutputPolicy

Inherits:
Object
  • Object
show all
Defined in:
lib/turnkit/output_policy.rb

Constant Summary collapse

DEFAULT_SCHEMA =
{
  type: "object",
  properties: {
    approved: { type: "boolean" },
    violations: {
      type: "array",
      items: {
        type: "object",
        properties: {
          rule: { type: "string" },
          message: { type: "string" }
        },
        required: [ "rule", "message" ]
      }
    }
  },
  required: [ "approved", "violations" ]
}.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(content:, name: "output_policy", model: nil, thinking: nil, client: nil) ⇒ OutputPolicy

Returns a new instance of OutputPolicy.

Raises:

  • (ArgumentError)


30
31
32
33
34
35
36
37
# File 'lib/turnkit/output_policy.rb', line 30

def initialize(content:, name: "output_policy", model: nil, thinking: nil, client: nil)
  @name = name.to_s
  @content = content.to_s
  @model = model
  @thinking = Agent.normalize_thinking(thinking)
  @client = client
  raise ArgumentError, "content is required" if @content.empty?
end

Instance Attribute Details

#clientObject (readonly)

Returns the value of attribute client.



24
25
26
# File 'lib/turnkit/output_policy.rb', line 24

def client
  @client
end

#contentObject (readonly)

Returns the value of attribute content.



24
25
26
# File 'lib/turnkit/output_policy.rb', line 24

def content
  @content
end

#modelObject (readonly)

Returns the value of attribute model.



24
25
26
# File 'lib/turnkit/output_policy.rb', line 24

def model
  @model
end

#nameObject (readonly)

Returns the value of attribute name.



24
25
26
# File 'lib/turnkit/output_policy.rb', line 24

def name
  @name
end

#thinkingObject (readonly)

Returns the value of attribute thinking.



24
25
26
# File 'lib/turnkit/output_policy.rb', line 24

def thinking
  @thinking
end

Class Method Details

.from_file(path, name: nil, **options) ⇒ Object



26
27
28
# File 'lib/turnkit/output_policy.rb', line 26

def self.from_file(path, name: nil, **options)
  new(name: name || File.basename(path, File.extname(path)), content: File.read(path), **options)
end

Instance Method Details

#call(output, run: nil, turn: nil) ⇒ Object



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/turnkit/output_policy.rb', line 39

def call(output, run: nil, turn: nil)
  model_name = model || turn&.model || run&.turn&.model || TurnKit.default_model
  result = if turn
    turn.internal_model_call(
      model: model_name,
      messages: audit_messages(output),
      tools: [],
      instructions: audit_instructions,
      thinking: thinking,
      output_schema: DEFAULT_SCHEMA,
      metadata: { output_policy: name },
      purpose: "output_policy",
      client: client
    )
  else
    audit_client = client || TurnKit.client
    audit_client.validate!(model: model_name)
    chat(audit_client, model: model_name, messages: audit_messages(output), tools: [], instructions: audit_instructions, thinking: thinking, output_schema: DEFAULT_SCHEMA, metadata: { output_policy: name })
  end
  data = result.output_data || parse_json(result.text)
  return if data.fetch("approved", false)

  Array(data["violations"]).map do |violation|
    attrs = violation.transform_keys(&:to_s)
    OutputAudit::Violation.new(
      rule: attrs["rule"] || name,
      message: attrs["message"] || "output policy failed",
      metadata: attrs.reject { |key, _| %w[rule message].include?(key) }
    )
  end
end