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 +4 -4
- data/lib/llm.rb +1 -1
- data/lib/llmed/application.rb +4 -7
- data/lib/llmed/configuration.rb +4 -4
- data/lib/llmed/context.rb +41 -2
- data/lib/llmed/release.rb +31 -19
- metadata +1 -1
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 48b4c352f5fd54aa841fe411fd7f5025f1c98f40b8a287589aeb46ad213def68
         | 
| 4 | 
            +
              data.tar.gz: c53e2efec6164261d6985f9297b101b363d1e9da432123ddeac1e369a7f045d2
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 1b228350f691be1762449160bafde3f3c3eba0cc180fd918207f09a855939d0ec784f53861f72304a61d6c4c2adfd525d4e29cf868c1bc1d1dbfb9aa0ff7ad15
         | 
| 7 | 
            +
              data.tar.gz: 7eea2cc52879f589c1b4612409c7c0923aa88135bcb705817966fb4827d449032cc528891140e37a088ff0145fe792982f068162b716785d41e5c3ac736a8bfd
         | 
    
        data/lib/llm.rb
    CHANGED
    
    
    
        data/lib/llmed/application.rb
    CHANGED
    
    | @@ -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. | 
| 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 | 
| 192 | 
            -
                        update_context_digest << user_contexts | 
| 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 | 
| 218 | 
            -
                    [ctx.name, ctx.digest]
         | 
| 219 | 
            -
                  end.to_h
         | 
| 216 | 
            +
                  UserContexts.new(@contexts)
         | 
| 220 217 | 
             
                end
         | 
| 221 218 |  | 
| 222 219 | 
             
                def release_contexts
         | 
    
        data/lib/llmed/configuration.rb
    CHANGED
    
    | @@ -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 | 
            -
             | 
| 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='....'  | 
| 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 | 
| 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 | 
            -
                     | 
| 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 | 
            -
                     | 
| 103 | 
            -
                    ctx.digest =  | 
| 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 | | 
| 108 | 
            -
                    next if contexts.any? { |ctx| ctx.name == name }
         | 
| 109 | 
            -
             | 
| 110 | 
            -
                     | 
| 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 | 
            -
                   | 
| 116 | 
            -
                   | 
| 117 | 
            -
             | 
| 118 | 
            -
             | 
| 119 | 
            -
             | 
| 120 | 
            -
             | 
| 121 | 
            -
             | 
| 122 | 
            -
             | 
| 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  | 
| 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='(.+?)' | 
| 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 | 
             
                              ''
         |