summarize-meeting 1.0.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 502d04b52ca4fb6aeba632d7d9959ef043db57cd7f70f9de278a5fc70f52a034
4
- data.tar.gz: b1aae558f143f92a5d21e0f5268025768ef517b1ace5773c5f4b44a0b9fab10d
3
+ metadata.gz: 50b154d8f5d117b51fb3a377ad725088262543c05d5ee2614929511ad093a553
4
+ data.tar.gz: 66f0a4144e8b5bf6d36792bdb0432014b803e4eff020060fc9d5045c1631edef
5
5
  SHA512:
6
- metadata.gz: 781f9a4108fce791c7355e73161922b1271d8c7aefadc878dedadc5dfeec5b7a408a454c0d93d20912dd897a16b8c017ea6a4fcda27d2859fd90e252538163ae
7
- data.tar.gz: 7b01038c1cd4a0473d98338131866fb751b471fcdffa49e91619ce12d0e83cf8dddf68814dbaf2c822e29d3d43c9260a0dbcb44d304f6bd4f4aee9e262ca8210
6
+ metadata.gz: fd077cdfe8a177d145a5ab4672d14477cbd7a06124f0eeb03c834ef5eb632022d76920ab1ee6cba38e81204f91faa48cb1bdcc1683a86db1f7305e232cc3380a
7
+ data.tar.gz: fc2061143753fc8865b39702cfc215ae7732f8e697f8288170f07a8ba1f627c3078f4d37c40e725506413a2718cb5b7b3f93d427cd6d94a3d1ee7f0d30246192
@@ -1,11 +1,17 @@
1
- require "openai"
2
-
3
1
  module SummarizeMeeting
4
2
  module Ai
3
+ class OpenAiError < StandardError; end
4
+ MAX_TOTAL_TOKENS = 4096
5
+ WORDS_PER_TOKEN = 0.75
6
+
5
7
  @@access_token = ENV["OPENAI_KEY"]
6
8
  @@organization_id = ENV["OPENAI_ORG"]
7
9
 
8
10
  def self.client
11
+ @client ||= new_client(access_token: access_token, organization_id: organization_id)
12
+ end
13
+
14
+ def self.new_client(access_token:, organization_id:)
9
15
  OpenAI::Client.new(access_token: access_token, organization_id: organization_id)
10
16
  end
11
17
 
@@ -24,5 +30,27 @@ module SummarizeMeeting
24
30
  def self.organization_id=(id)
25
31
  @@organization_id = id
26
32
  end
33
+
34
+ def self.calculate_token_word_count(token_count)
35
+ (token_count * WORDS_PER_TOKEN.to_f).ceil
36
+ end
37
+
38
+ def self.calculate_word_token_count(word_count)
39
+ (word_count / WORDS_PER_TOKEN.to_f).ceil
40
+ end
41
+
42
+ def self.chat(messages, client: self.client)
43
+ parameters = {
44
+ model: "gpt-3.5-turbo",
45
+ messages: messages,
46
+ }
47
+ response = client.chat(parameters: parameters)
48
+ content = response.dig("choices", 0, "message", "content")
49
+ if !content
50
+ raise OpenAiError, "No response from OpenAI"
51
+ else
52
+ content
53
+ end
54
+ end
27
55
  end
28
56
  end
@@ -4,6 +4,8 @@ require "openai"
4
4
 
5
5
  module SummarizeMeeting
6
6
  class Meeting
7
+ RESPONSE_RESERVE_TOKENS = 500
8
+
7
9
  LINE_SUMMARY_PROMPT_TEMPLATE = [
8
10
  {
9
11
  role: "system",
@@ -11,7 +13,7 @@ module SummarizeMeeting
11
13
  },
12
14
  {
13
15
  role: "system",
14
- content: "The transcript of the meeting is split into {{chunkCount}} chunks. This is the {{chunkIndex}} chunk.",
16
+ content: "The transcript of the meeting is split into {{chunkCount}} chunks. This is the chunk number {{chunkIndex}} of {{chunkCount}}.",
15
17
  },
16
18
  {
17
19
  role: "assistant",
@@ -60,17 +62,14 @@ module SummarizeMeeting
60
62
  attr_reader :transcript
61
63
 
62
64
  def summarize
63
-
64
65
  # Step 1. Split the transcript into lines.
65
66
  lines = transcript.lines
66
67
 
67
68
  # Step 2. Calculate the maximum chunk size in words.
68
- max_total_tokens = 4000
69
- response_token_reserve = 500
70
- template_tokens = LINE_SUMMARY_PROMPT_TEMPLATE.map { |line| line[:content].split.size }.sum
71
- max_chunk_tokens = max_total_tokens - response_token_reserve - template_tokens
72
- words_per_token = 0.7
73
- max_chunk_word_count = max_chunk_tokens * words_per_token
69
+ template_word_count = LINE_SUMMARY_PROMPT_TEMPLATE.map { |line| line[:content].split.size }.sum
70
+ template_token_count = SummarizeMeeting::Ai.calculate_word_token_count(template_word_count)
71
+ max_chunk_token_count = SummarizeMeeting::Ai::MAX_TOTAL_TOKENS - RESPONSE_RESERVE_TOKENS - template_token_count
72
+ max_chunk_word_count = SummarizeMeeting::Ai.calculate_token_word_count(max_chunk_token_count)
74
73
 
75
74
  # Step 3. Split the transcript into equally sized chunks.
76
75
  chunks = split_lines_into_equal_size_chunks(lines, max_chunk_word_count)
@@ -86,27 +85,14 @@ module SummarizeMeeting
86
85
  consolidated_template = CONSOLIDATED_SUMMARY_PROMPT_TEMPLATE
87
86
  prompt = Mustache.render(consolidated_template.to_json, { notes: previous_chunks_summary.to_json })
88
87
  messages = JSON.parse(prompt)
89
- response = SummarizeMeeting::Ai.client.chat(
90
- parameters: {
91
- model: "gpt-3.5-turbo",
92
- messages: messages,
93
- }
94
- )
95
- response.dig("choices", 0, "message", "content")
88
+ SummarizeMeeting::Ai.chat(messages)
96
89
  end
97
90
 
98
91
  def summarize_chunk(chunk, chunk_index, chunk_count, previous_chunks_summary)
99
92
  template = LINE_SUMMARY_PROMPT_TEMPLATE
100
93
  prompt = Mustache.render(template.to_json, { chunkCount: chunk_count, chunkIndex: chunk_index + 1, chunk: chunk.join("\n").to_json })
101
94
  messages = JSON.parse(prompt)
102
-
103
- response = SummarizeMeeting::Ai.client.chat(
104
- parameters: {
105
- model: "gpt-3.5-turbo",
106
- messages: messages,
107
- }
108
- )
109
- response.dig("choices", 0, "message", "content")
95
+ SummarizeMeeting::Ai.chat(messages)
110
96
  end
111
97
 
112
98
  def split_lines_into_equal_size_chunks(lines, max_chunk_word_count)
@@ -1,3 +1,3 @@
1
1
  module SummarizeMeeting
2
- VERSION = "1.0.0"
2
+ VERSION = "1.2.0"
3
3
  end
@@ -3,4 +3,4 @@ require_relative "./summarize-meeting/ai"
3
3
  require_relative "./summarize-meeting/meeting"
4
4
 
5
5
  module SummarizeMeeting
6
- end
6
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: summarize-meeting
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sean Devine
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-03-03 00:00:00.000000000 Z
11
+ date: 2023-03-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: optparse