llmed 0.4.3 → 0.4.4

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: 5733bac9f8a6d8c5465f487bda233c8997491d838c778b45194e3c15f9c14734
4
- data.tar.gz: e606c3e377bc6d0bf75eed59dd6456773c02650e98118a0135814808195e2fb8
3
+ metadata.gz: 48b4c352f5fd54aa841fe411fd7f5025f1c98f40b8a287589aeb46ad213def68
4
+ data.tar.gz: c53e2efec6164261d6985f9297b101b363d1e9da432123ddeac1e369a7f045d2
5
5
  SHA512:
6
- metadata.gz: 3fc77a1b7b7ca6ba6c8bcb528e1ef702277588195c47e538cfa6a8432aef4ae7cb876b10537605866bfa7ea0a61ceacf1308cd52d3b5f0f2a7a4f51ef5b552ed
7
- data.tar.gz: 94f66750f04e2c97d8e78125ac920c52037fd6bc5e5759cbd2e349402be599619fb5cb2dc92af0c519a0cc557333be022925abb556f09995460a0b0d936386c8
6
+ metadata.gz: 1b228350f691be1762449160bafde3f3c3eba0cc180fd918207f09a855939d0ec784f53861f72304a61d6c4c2adfd525d4e29cf868c1bc1d1dbfb9aa0ff7ad15
7
+ data.tar.gz: 7eea2cc52879f589c1b4612409c7c0923aa88135bcb705817966fb4827d449032cc528891140e37a088ff0145fe792982f068162b716785d41e5c3ac736a8bfd
data/lib/llm.rb CHANGED
@@ -56,7 +56,7 @@ class LLMed
56
56
  @logger.warn("POSSIBLE INCONSISTENCY COMPLETED TOKENS REACHED MAX TOKENS #{MAX_TOKENS}")
57
57
  end
58
58
  end
59
-
59
+
60
60
  def llm_arguments(args)
61
61
  args
62
62
  end
@@ -134,9 +134,8 @@ class LLMed
134
134
  !digests_of_context_to_update.tap do |digests|
135
135
  digests.each do |digest|
136
136
  context_by_digest = release_contexts.invert
137
-
138
137
  if context_by_digest[digest].nil?
139
- @logger.info("APPLICATION #{@name} ADDING CONTEXT #{user_contexts.invert[digest]}")
138
+ @logger.info("APPLICATION #{@name} ADDING CONTEXT #{user_contexts.by_digest(digest).name}")
140
139
  else
141
140
  @logger.info("APPLICATION #{@name} REBUILDING CONTEXT #{context_by_digest[digest]}")
142
141
  end
@@ -188,8 +187,8 @@ class LLMed
188
187
  end
189
188
 
190
189
  # added new context
191
- if !release_context.digest? && !user_contexts[ctx.name].nil?
192
- update_context_digest << user_contexts[ctx.name]
190
+ if !release_context.digest? && !user_contexts.by_name(ctx.name).nil?
191
+ update_context_digest << user_contexts.by_name(ctx.name).digest
193
192
  next
194
193
  elsif release_context.digest? && !ctx.same_digest?(release_context.digest)
195
194
  update_rest = true
@@ -214,9 +213,7 @@ class LLMed
214
213
  end
215
214
 
216
215
  def user_contexts
217
- @contexts.map do |ctx|
218
- [ctx.name, ctx.digest]
219
- end.to_h
216
+ UserContexts.new(@contexts)
220
217
  end
221
218
 
222
219
  def release_contexts
@@ -12,22 +12,22 @@ Don't make any assumptions/expectations or wait for implementations, always impl
12
12
  The contexts are declarations of how the source code will be (not a file) ensure to follow this always.
13
13
  The contexts are connected as a flat linked list.
14
14
  All the contexts represent one source code.
15
- There is always a one-to-one correspondence between context and source code.
15
+ Always exists one-to-one correspondence between context and source code.
16
16
  Always include the properly escaped comment: LLMED-COMPILED.
17
17
 
18
18
  You must only modify the following source code:
19
- ```
19
+ ```{language}
20
20
  {source_code}
21
21
  ```
22
22
 
23
23
  Only generate source code of the context who digest belongs to {update_context_digests}.
24
24
 
25
25
  Wrap with comment every code that belongs to the indicated context, example in {language}:
26
- {code_comment_begin}<llmed-code context='context name' digest='....' after='digest next context'>{code_comment_end}
26
+ {code_comment_begin}<llmed-code context='here context name' digest='....' link-digest='next digest' after='here same value of attribute link-digest'>{code_comment_end}
27
27
  ...
28
28
  {code_comment_begin}</llmed-code>{code_comment_end}
29
29
 
30
- !!Your response must contain only the generated source code, with no additional text or comments, and you must ensure that runs correctly on the first attempt.
30
+ !!Your response must contain only the generated source code with all indicated contexts, with no additional text or comments, and you must ensure that runs correctly on the first attempt.
31
31
  ", input_variables: %w[language source_code code_comment_begin code_comment_end update_context_digests])
32
32
  end
33
33
 
data/lib/llmed/context.rb CHANGED
@@ -1,14 +1,53 @@
1
1
  # Copyright 2025 Jovany Leandro G.C <bit4bit@riseup.net>
2
2
  # frozen_string_literal: true
3
+
3
4
  require 'erb'
4
5
 
5
6
  class LLMed
7
+ class UserContexts
8
+ def initialize(contexts)
9
+ @contexts = contexts.dup
10
+ end
11
+
12
+ def each(&block)
13
+ @contexts.each(&block)
14
+ end
15
+
16
+ def empty?
17
+ @contexts.empty?
18
+ end
19
+
20
+ def [](idx)
21
+ @contexts[idx]
22
+ end
23
+
24
+ def each_with_next(&block)
25
+ @contexts.each_with_index do |ctx, idx|
26
+ next_ctx = @contexts[idx + 1]
27
+ block.call(ctx, next_ctx)
28
+ end
29
+ end
30
+
31
+ def count
32
+ @contexts.count
33
+ end
34
+
35
+ def by_name(name)
36
+ @contexts.find { |ctx| ctx.name == name }
37
+ end
38
+
39
+ def by_digest(digest)
40
+ @contexts.find { |ctx| ctx.same_digest?(digest) }
41
+ end
42
+ end
43
+
6
44
  class Context
7
45
  attr_reader :name
8
46
 
9
- def initialize(name:, options: {})
47
+ def initialize(name:, digest: nil, options: {})
10
48
  @name = name
11
49
  @skip = options[:skip] || false
50
+ @fixed_digest = digest || nil
12
51
  @release_dir = options[:release_dir]
13
52
  end
14
53
 
@@ -21,7 +60,7 @@ class LLMed
21
60
  end
22
61
 
23
62
  def digest
24
- Digest::SHA256.hexdigest "#{@name}.#{@message}"
63
+ @fixed_digest || Digest::SHA256.hexdigest("#{@name}.#{@message}")
25
64
  end
26
65
 
27
66
  def message
data/lib/llmed/release.rb CHANGED
@@ -5,7 +5,8 @@ class LLMed
5
5
  class Release
6
6
  ContextCode = Struct.new(:name, :digest, :code, :after) do
7
7
  def to_llmed_code(code_comment)
8
- "#{code_comment.begin}<llmed-code context='#{name}' digest='#{digest}' after='#{after}'>#{code_comment.end}#{code}#{code_comment.begin}</llmed-code>#{code_comment.end}"
8
+ close_newline = "\n" if code.strip.empty?
9
+ "#{code_comment.begin}<llmed-code context='#{name}' digest='#{digest}' after='#{after}'>#{code_comment.end}#{code}#{close_newline}#{code_comment.begin}</llmed-code>#{code_comment.end}"
9
10
  end
10
11
 
11
12
  def digest?
@@ -99,42 +100,53 @@ class LLMed
99
100
 
100
101
  # fix user contexts digest
101
102
  contexts.each do |ctx|
102
- user_context_digest = user_contexts[ctx.name]
103
- ctx.digest = user_context_digest unless user_context_digest.nil?
103
+ user_context = user_contexts.by_name(ctx.name)
104
+ ctx.digest = user_context.digest unless user_context.nil?
104
105
  end
105
106
 
106
107
  # insertions missed user contexts
107
- user_contexts.each do |name, digest|
108
- next if contexts.any? { |ctx| ctx.name == name }
109
- code = release.context_by(name).code
110
- new_ctx = ContextCode.new(name, digest, code, '')
108
+ user_contexts.each do |user_context|
109
+ next if contexts.any? { |ctx| ctx.name == user_context.name }
110
+
111
+ code = release.context_by(user_context.name).code
112
+ new_ctx = ContextCode.new(user_context.name, user_context.digest, code, '')
111
113
  contexts.prepend(new_ctx)
112
114
  @changes << [:added, new_ctx]
113
115
  end
114
116
 
115
- contexts_sorted = []
116
- # prioritize user order
117
- user_contexts.each do |name, _digest|
118
- contexts.each do |ctx|
119
- if ctx.name == name
120
- contexts_sorted << ctx
121
- break
122
- end
123
- end
117
+ # code context must have the same order as user contexts
118
+ if user_contexts.empty?
119
+ contexts_sorted = contexts
120
+ else
121
+ user_contexts_iter = user_contexts.dup
122
+ contexts_iter = contexts.dup
123
+ rewire_code_contexts(contexts_iter, user_contexts_iter)
124
+ contexts_sorted = contexts_iter
124
125
  end
125
126
 
126
- @contexts = contexts_sorted.sort {|a,b|
127
+ @contexts = contexts_sorted.sort do |a, b|
127
128
  if a.digest == b.after
128
129
  1
129
130
  else
130
131
  0
131
132
  end
132
- }
133
+ end
134
+
133
135
  self
134
136
  end
135
137
 
136
138
  private
137
139
 
140
+ def rewire_code_contexts(code_contexts, user_contexts)
141
+ user_contexts.each_with_next do |user_context, next_user_context|
142
+ ctx = code_contexts.find { |ctx| ctx.digest == user_context.digest }
143
+ if ctx
144
+ ctx.after = '' if user_contexts.count > 1
145
+ ctx.after = next_user_context.digest if next_user_context
146
+ end
147
+ end
148
+ end
149
+
138
150
  def initialize(origin, code_comment)
139
151
  @origin = origin
140
152
  @content = ''
@@ -142,7 +154,7 @@ class LLMed
142
154
  @code_comment = code_comment
143
155
  @contexts = []
144
156
 
145
- @origin.scan(%r{<llmed-code context='(.+?)' digest='(.+?)'\s*(after='.*?')?>#{@code_comment.end}(.+?)#{@code_comment.begin}+\s*<?/?llmed-code}im).each do |match|
157
+ @origin.scan(%r{<llmed-code context='(.+?)' digest='(.+?)'(?:\s+[^>]*?)?(after='.*?')?>#{@code_comment.end}(.+?)#{@code_comment.begin}+\s*<?/?llmed-code}im).each do |match|
146
158
  name, digest, after_block, code = match
147
159
  after = if after_block.nil?
148
160
  ''
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: llmed
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.3
4
+ version: 0.4.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jovany Leandro G.C