Class: Assistant

Inherits:
Object
  • Object
show all
Defined in:
lib/newsman/assistant.rb

Overview

This class mimics a robot that can analyse a developer activity. The assistant uses OpenAI API to analyze.

Constant Summary collapse

FIXED_TEMPERATURE_MODELS =

OpenAI's reasoning-family models (o1, o3, o4-mini, gpt-5, ...) only accept the default temperature (1) and reject any explicit value with a 400. Their "-chat" flavors (e.g. gpt-5-chat-latest) are non-reasoning and support a custom temperature just like gpt-4o, gpt-3.5-turbo, etc.

/\A(o[1-9]|gpt-5)/
SYSTEM_PROMPT =
'You are a developer tasked with composing a concise report detailing'\
' your activities and progress for the previous week, intended for submission to your supervisor.'

Instance Method Summary collapse

Constructor Details

#initialize(token, model: 'gpt-3.5-turbo', temperature: 0.3) ⇒ Assistant

Returns a new instance of Assistant.



28
29
30
31
32
33
# File 'lib/newsman/assistant.rb', line 28

def initialize(token, model: 'gpt-3.5-turbo', temperature: 0.3)
  @token = token
  @model = model
  @temperature = temperature
  @client = OpenAI::Client.new(access_token: token)
end

Instance Method Details

#deprecated(method) ⇒ Object



148
149
150
# File 'lib/newsman/assistant.rb', line 148

def deprecated(method)
  warn "Warning! '#{method}' is deprecated and will be removed in future versions."
end

#fixed_temperature?Boolean

Returns:

  • (Boolean)


133
134
135
# File 'lib/newsman/assistant.rb', line 133

def fixed_temperature?
  @model.match?(FIXED_TEMPERATURE_MODELS) && !@model.include?('chat')
end

#format(report) ⇒ Object

rubocop:enable Metrics/MethodLength



108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/newsman/assistant.rb', line 108

def format(report)
  prompt = <<~PROMPT
    I have a weekly report with different parts that use various formatting styles.
    Please format the entire report into a single cohesive format while preserving the original text without any changes.
    Ensure that the formatting is consistent throughout the document.

    Here is the report:

    #{report}
  PROMPT
  send(prompt)
end

#messages(request) ⇒ Object



140
141
142
143
144
145
146
# File 'lib/newsman/assistant.rb', line 140

def messages(request)
  if @model == 'o1-preview'
    [{ role: 'user', content: request.to_s }]
  else
    [{ role: 'system', content: SYSTEM_PROMPT }, { role: 'user', content: request.to_s }]
  end
end

#next_plans(issues) ⇒ Object

rubocop:disable Metrics/MethodLength



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/newsman/assistant.rb', line 44

def next_plans(issues)
  example = "repository-name:\n
    - To publish ABC package draft [#27]\n
    - To review first draft of the report [#56]\n
    - To implement optimization for the class X [#125]\n
    - Updated dependencies: rubocop, ruby [#197, #199, #204]"
  prompt = <<~PROMPT
    Please compile a summary of the plans for the next week using the GitHub Issues.
    Each issue should be summarized in a single sentence.
    Combine all the information from each Issue into a concise and fluent sentence.
    Pay attention, that you didn't loose any issue.
    Ensure that each sentence includes the corresponding issue number as an integer value. If an issue doesn't mention an issue number, just print [#chore].
    If several issues have the same number, combine them into a single sentence.
    Dependency version-bump issues (e.g. titles like "chore(deps): update dependency X to vY" or similar renovate/dependabot style bumps) must all be grouped into a single combined bullet listing the dependency names and all associated issue numbers, instead of one bullet per issue.
    Other substantive issues should keep their own individual bullet as usual.
    Please strictly adhere to the example template provided: "#{example}".
    List of GitHub Issues in JSON format: ```json #{issues}```.
  PROMPT
  send(prompt)
end

#prev_results(prs) ⇒ Object

rubocop:disable Metrics/MethodLength



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/newsman/assistant.rb', line 67

def prev_results(prs)
  example = "repository-name:\n
    - Added 100 new files to the Dataset [#168]\n
    - Fixed the deployment of XYZ [#169]\n
    - Refined the requirements [#177]\n
    - Updated dependencies: rubocop, ruby, nokogiri [#197, #199, #200, #202, #203, #204]\n"
  prompt = <<~PROMPT
    Please compile a summary of the work completed in the following Pull Requests (PRs).
    Each PR should be summarized in a single sentence, focusing on the PR title rather than the implementation details.
    Ensure no PR is omitted.
    Each sentence must include the corresponding issue number as an integer value. If a PR does not mention an issue number, use [#chore].
    If several PRs have the same number, combine them into a single sentence.
    Dependency version-bump PRs (e.g. titles like "chore(deps): update dependency X to vY" or similar renovate/dependabot style bumps) must all be grouped into a single combined bullet listing the dependency names and all associated PR numbers, instead of one bullet per PR.
    Other substantive PRs should keep their own individual bullet as usual.
    Combine the information from each PR into a concise and fluent sentence.
    Follow the provided example template strictly: "#{example}".
    List of Pull Requests in JSON format: ```json #{prs}```.
  PROMPT
  send(prompt)
end

#risks(all) ⇒ Object

rubocop:disable Metrics/MethodLength



90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/newsman/assistant.rb', line 90

def risks(all)
  example = "repository-name:\n
    - The server is weak, we may fail the delivery\n
    of the dataset, report milestone will be missed [#487].\n
    - The code in repository is suboptimal, we might have some problems for the future maintainability [#44].\n"
  prompt = <<~PROMPT
    Please compile a summary of the risks identified in the repository from the list of pull requests provided.
    If no risks are identified in a pull request, just answer 'No risks identified' for that PR.
    Each risk should be summarized in a concise and fluent single sentence.
    Developers usually mention some risks in pull request descriptions, either as 'risk' or 'issue'.#{' '}
    Ensure that each sentence includes the corresponding PR number as an integer value. If a PR doesn't mention an issue number, just print [#chore].
    Please strictly adhere to the example template provided: "#{example}".
    List of Pull Requests: ```json #{all}```.
  PROMPT
  send(prompt)
end

#say_helloObject



35
36
37
38
39
40
41
# File 'lib/newsman/assistant.rb', line 35

def say_hello
  <<~HELLO
    I'm an assistant that can work with OpenAI client.
    Please, use me, if you need any help.
    I'm using #{@model}, with #{@temperature} temperature.
  HELLO
end

#send(request) ⇒ Object



127
128
129
130
131
# File 'lib/newsman/assistant.rb', line 127

def send(request)
  parameters = { model: @model, messages: messages(request) }
  parameters[:temperature] = @temperature unless fixed_temperature?
  @client.chat(parameters: parameters).dig('choices', 0, 'message', 'content')
end