pedicab 0.3.1 → 0.3.3

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.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/API.md +401 -0
  3. data/EXAMPLES.md +884 -0
  4. data/Gemfile.lock +10 -24
  5. data/INSTALLATION.md +652 -0
  6. data/README.md +329 -10
  7. data/lib/pedicab/#city.rb# +27 -0
  8. data/lib/pedicab/ride.rb +60 -81
  9. data/lib/pedicab/version.rb +1 -1
  10. data/lib/pedicab.py +3 -8
  11. data/lib/pedicab.rb +141 -133
  12. metadata +6 -89
  13. data/#README.md# +0 -51
  14. data/books/Arnold_Bennett-How_to_Live_on_24_Hours_a_Day.txt +0 -1247
  15. data/books/Edward_L_Bernays-crystallizing_public_opinion.txt +0 -4422
  16. data/books/Emma_Goldman-Anarchism_and_Other_Essays.txt +0 -7654
  17. data/books/Office_of_Strategic_Services-Simple_Sabotage_Field_Manual.txt +0 -1057
  18. data/books/Sigmund_Freud-Group_Psychology_and_The_Analysis_of_The_Ego.txt +0 -2360
  19. data/books/Steve_Hassan-The_Bite_Model.txt +0 -130
  20. data/books/Steve_Hassan-The_Bite_Model.txt~ +0 -132
  21. data/books/Sun_Tzu-Art_of_War.txt +0 -159
  22. data/books/Sun_Tzu-Art_of_War.txt~ +0 -166
  23. data/books/US-Constitution.txt +0 -502
  24. data/books/US-Constitution.txt~ +0 -502
  25. data/books/cia-kubark.txt +0 -4637
  26. data/books/machiavelli-the_prince.txt +0 -4599
  27. data/books/sun_tzu-art_of_war.txt +0 -1017
  28. data/books/us_army-bayonette.txt +0 -843
  29. data/lib/pedicab/calc.rb~ +0 -8
  30. data/lib/pedicab/link.rb +0 -38
  31. data/lib/pedicab/link.rb~ +0 -14
  32. data/lib/pedicab/mark.rb +0 -9
  33. data/lib/pedicab/mark.rb~ +0 -5
  34. data/lib/pedicab/on.rb +0 -6
  35. data/lib/pedicab/on.rb~ +0 -6
  36. data/lib/pedicab/poke.rb +0 -14
  37. data/lib/pedicab/poke.rb~ +0 -15
  38. data/lib/pedicab/query.rb +0 -92
  39. data/lib/pedicab/query.rb~ +0 -93
  40. data/lib/pedicab/rank.rb +0 -92
  41. data/lib/pedicab/rank.rb~ +0 -89
  42. data/lib/pedicab/ride.rb~ +0 -101
  43. data/lib/pedicab.sh~ +0 -3
data/lib/pedicab/calc.rb~ DELETED
@@ -1,8 +0,0 @@
1
- module Pedicab
2
- class Calc
3
- def initialize
4
-
5
- end
6
-
7
- end
8
- end
data/lib/pedicab/link.rb DELETED
@@ -1,38 +0,0 @@
1
- module LINK
2
- @@L = {}
3
- def self.on
4
- @@L
5
- end
6
- def self.each_pair &b
7
- @@L.each_pair { |k,v| b.call(k,v) }
8
- end
9
- end
10
-
11
- LINK.on["named entites which need to be defined or calculated"] = lambda { |s,e|
12
- s.each("each named entity", e) { |ee|
13
- if s.gate "The following has a calculatable formula:\n#{ee}"
14
- s.prompt("Respond with only the bare mathmatical formula to be calculated by the ruby eqn gem for the following:\n#{ee}")
15
- else
16
- s.prompt("Define the following in the simplest terms:\n#{ee}")
17
- end
18
- }
19
- }
20
-
21
- LINK.on["a single fact based answer"] = lambda { |s,e| s.prompt("Respond with the fact needed to correctly respond to the following:\n#{e}") }
22
-
23
- LINK.on["a step by step plan"] = lambda { |s,e| s.prompt("Respond with only a plan for the following without repeating yourself:\n#{e}").gsub(/\n\n+/,"\n") }
24
-
25
- LINK.on["an answer by logical progression of thought"] = lambda { |s,e| s.prompt("Outline your thinking about the following without repeating yourself:\n#{e}").gsub(/\n\n+/,"\n") }
26
-
27
- #LINK.on["goals which need to be achieved"] = lambda { |s,e|
28
- # s.each("all goals which need to be achieved", e) { |ee|
29
- # s.prompt("Outline the steps necessary to accomplish the following:\n#{ee}")
30
- # }
31
- #}
32
-
33
- #LINK.on["decisions which need to be made"] = lambda { |s,e|
34
- # s.each("all decisions which need to be made", e) { |ee|
35
- # s.prompt("Decide the following:\n#{ee}")
36
- # }
37
- #}
38
-
data/lib/pedicab/link.rb~ DELETED
@@ -1,14 +0,0 @@
1
- module LINK
2
- @@L = {}
3
- def self.on
4
- @@L
5
- end
6
- def self.each_pair &b
7
- @@L.each_pair { |k,v| b.call(k,v) }
8
- end
9
- end
10
-
11
- LINK.on["calculating a mathmatical formula"] = lambda { |s,e| s.dispatch("Define the mathmatical formula equal to the following:\n#{e} = ") }
12
- LINK.on["abstract or complex planning"] = lambda { |s,e| s.dispatch("Create a plan for the following:\n#{e}") }
13
- LINK.on["an answer by logical progression of thought"] = lambda { |s,e| s.dispath("Outline your thinking about the following:\n#{e}") }
14
- #LINK.on["fact based knowledge from known and trusted sources"] = lambda { |s,e| s.prompt("Respond with only the answer to the following with no formatting or punctuation in as few words as possible:\n#{e}") }
data/lib/pedicab/mark.rb DELETED
@@ -1,9 +0,0 @@
1
- module Pedicab
2
- def self.mark x
3
- Nokogiri::HTML(Redcarpet::Markdown.new(Redcarpet::Render::HTML, autolink: true).render(x)).css('p').map { |e|
4
- if !/http.*/.match(e.text)
5
- e.text
6
- end
7
- }.flatten.compact
8
- end
9
- end
data/lib/pedicab/mark.rb~ DELETED
@@ -1,5 +0,0 @@
1
- module Pedicab
2
- def self.mark x
3
- Redcarpet::Markdown.new(Redcarpet::Render::HTML, autolink: true, tables: true).render(x)
4
- end
5
- end
data/lib/pedicab/on.rb DELETED
@@ -1,6 +0,0 @@
1
- module Pedicab
2
- @@ON = Hash.new { |h,k| h[k] = lambda() { |ride| ride } }
3
- def self.on
4
- @@ON
5
- end
6
- end
data/lib/pedicab/on.rb~ DELETED
@@ -1,6 +0,0 @@
1
- module Pedicab
2
- @@ON = Hash.new { |h,k| h[k] = lambda() { |ride| ride } }
3
- def self.on
4
- @@ON
5
- end
6
- end
data/lib/pedicab/poke.rb DELETED
@@ -1,14 +0,0 @@
1
- module POKE
2
- @@POKE = {}
3
- def self.on
4
- @@POKE
5
- end
6
- def self.[] q
7
- a = [ q ]
8
- @@POKE.each_pair { |r,b| if m = Regexp.new(r).match(q); a << b.call(q, m); end; }
9
- return a.reverse.join("\n")
10
- end
11
- end
12
-
13
- POKE.on[" time "] = lambda { |q, m| t = Time.now; %[The current time is #{t.strftime('%T')}.] }
14
- POKE.on[" date "] = lambda { |q, m| t = Time.now; %[The current date is #{t.strftime('%D')}.] }
data/lib/pedicab/poke.rb~ DELETED
@@ -1,15 +0,0 @@
1
- module POKE
2
- @@POKE = {}
3
- def self.on
4
- @@POKE
5
- end
6
- def self.[] q
7
- a = [ q ]
8
- @@POKE.each_pair { |r,b| if m = Regexp.new(r).match(q); a << b.call(q, m); end; }
9
- return a.reverse.join("\n")
10
- end
11
- end
12
-
13
- POKE.on["time"] = lambda { |q, m| t = Time.now; %[The current time is #{t.strftime('%T')}.] }
14
- POKE.on["date"] = lambda { |q, m| t = Time.now; %[The current date is #{t.strftime('%D')}.] }
15
- POKE.on[/ (\d+)d(\d+) /] = lambda { |q, m| a, t = [], 0; m[1].to_i.times { x = rand(m[2].to_i) + 1; t += x; a << x }; %[Rolling #{m[1]}d#{m[2]} gave #{a.join(', ')} for a total of #{t}.] }
data/lib/pedicab/query.rb DELETED
@@ -1,92 +0,0 @@
1
- module Pedicab
2
- class RedditQuery
3
- include HTTParty
4
- base_uri 'https://www.reddit.com'
5
-
6
- # Set a custom user agent (Reddit requires this)
7
- headers 'User-Agent' => 'Ruby Reddit Client/1.0'
8
-
9
- def initialize(topic)
10
- @topic = topic
11
- end
12
-
13
- # Search for posts about the topic
14
- def search(limit: 25, sort: 'relevance', time: 'all')
15
- options = {
16
- query: {
17
- q: @topic,
18
- limit: limit,
19
- sort: sort,
20
- t: time,
21
- raw_json: 1
22
- }
23
- }
24
-
25
- response = self.class.get('/search.json', options)
26
- parse_response(response)
27
- end
28
-
29
- # Get posts from a specific subreddit about the topic
30
- def search_subreddit(subreddit, limit: 25, sort: 'hot')
31
- options = {
32
- query: {
33
- limit: limit,
34
- raw_json: 1
35
- }
36
- }
37
-
38
- response = self.class.get("/r/#{subreddit}/search.json?q=#{@topic}&restrict_sr=1", options)
39
- parse_response(response)
40
- end
41
-
42
- # Get hot posts from a subreddit
43
- def get_subreddit_posts(subreddit, limit: 25, sort: 'hot')
44
- options = {
45
- query: {
46
- limit: limit,
47
- raw_json: 1
48
- }
49
- }
50
-
51
- response = self.class.get("/r/#{subreddit}/#{sort}.json", options)
52
- parse_response(response)
53
- end
54
-
55
- private
56
-
57
- def parse_response(response)
58
- if response.success?
59
- data = response.parsed_response
60
- posts = data.dig('data', 'children') || []
61
-
62
- posts.map do |post|
63
- post_data = post['data']
64
- {
65
- title: post_data['title'],
66
- author: post_data['author'],
67
- subreddit: post_data['subreddit'],
68
- score: post_data['score'],
69
- url: post_data['url'],
70
- permalink: "https://www.reddit.com#{post_data['permalink']}",
71
- created_utc: Time.at(post_data['created_utc']),
72
- num_comments: post_data['num_comments'],
73
- selftext: post_data['selftext']
74
- }
75
- end
76
- else
77
- puts "Error: #{response.code} - #{response.message}"
78
- []
79
- end
80
- end
81
- end
82
-
83
- # Example usage:
84
- def self.reddit q
85
- qq = RedditQuery.new(q).search(limit: 10, sort: 'hot', time: 'week').map { |post|
86
- p = post[:selftext];
87
- if p.length > 0;
88
- p;
89
- end;
90
- }.flatten.compact
91
- end
92
- end
@@ -1,93 +0,0 @@
1
- module Pedicab
2
- class RedditQuery
3
- include HTTParty
4
- base_uri 'https://www.reddit.com'
5
-
6
- # Set a custom user agent (Reddit requires this)
7
- headers 'User-Agent' => 'Ruby Reddit Client/1.0'
8
-
9
- def initialize(topic)
10
- @topic = topic
11
- end
12
-
13
- # Search for posts about the topic
14
- def search(limit: 25, sort: 'relevance', time: 'all')
15
- options = {
16
- query: {
17
- q: @topic,
18
- limit: limit,
19
- sort: sort,
20
- t: time,
21
- raw_json: 1
22
- }
23
- }
24
-
25
- response = self.class.get('/search.json', options)
26
- parse_response(response)
27
- end
28
-
29
- # Get posts from a specific subreddit about the topic
30
- def search_subreddit(subreddit, limit: 25, sort: 'hot')
31
- options = {
32
- query: {
33
- limit: limit,
34
- raw_json: 1
35
- }
36
- }
37
-
38
- response = self.class.get("/r/#{subreddit}/search.json?q=#{@topic}&restrict_sr=1", options)
39
- parse_response(response)
40
- end
41
-
42
- # Get hot posts from a subreddit
43
- def get_subreddit_posts(subreddit, limit: 25, sort: 'hot')
44
- options = {
45
- query: {
46
- limit: limit,
47
- raw_json: 1
48
- }
49
- }
50
-
51
- response = self.class.get("/r/#{subreddit}/#{sort}.json", options)
52
- parse_response(response)
53
- end
54
-
55
- private
56
-
57
- def parse_response(response)
58
- if response.success?
59
- data = response.parsed_response
60
- posts = data.dig('data', 'children') || []
61
-
62
- posts.map do |post|
63
- post_data = post['data']
64
- {
65
- title: post_data['title'],
66
- author: post_data['author'],
67
- subreddit: post_data['subreddit'],
68
- score: post_data['score'],
69
- url: post_data['url'],
70
- permalink: "https://www.reddit.com#{post_data['permalink']}",
71
- created_utc: Time.at(post_data['created_utc']),
72
- num_comments: post_data['num_comments'],
73
- selftext: post_data['selftext']
74
- }
75
- end
76
- else
77
- puts "Error: #{response.code} - #{response.message}"
78
- []
79
- end
80
- end
81
- end
82
-
83
- # Example usage:
84
- def self.reddit q
85
- qq = RedditQuery.new(q).search(limit: 10, sort: 'hot', time: 'week').map { |post|
86
- p = post[:selftext];
87
- if p.length > 0;
88
- p;
89
- end;
90
- }.flatten.compact.join("\n")
91
- return %[#{q}:\n#{qq}]
92
- end
93
- end
data/lib/pedicab/rank.rb DELETED
@@ -1,92 +0,0 @@
1
- module Pedicab
2
- module RANK
3
- class KNN
4
- # Initialize with a collection of strings
5
- def initialize(strings)
6
- @strings = strings
7
- end
8
-
9
- # Find k nearest neighbors to the query string
10
- # Returns array of hashes with :string, :distance, and :similarity
11
- def rank(id, query, k = 5, method: :levenshtein)
12
- a, t = id.split("-")
13
- return [] if @strings.empty?
14
-
15
- # Calculate distances for all strings
16
- distances = @strings.map do |str|
17
- dist = levenshtein_distance(query, str)
18
- {
19
- book: id,
20
- author: a,
21
- title: t,
22
- string: str.strip,
23
- distance: dist,
24
- similarity: 1.0 / (1.0 + dist)
25
- }
26
- end
27
-
28
- # Sort by distance (ascending) and take k nearest
29
- distances.sort_by { |d| d[:distance] }.take([k, @strings.length].min)
30
- end
31
-
32
- private
33
-
34
- # Calculate Levenshtein distance between two strings
35
- def levenshtein_distance(s1, s2)
36
- s1_lower = s1.downcase
37
- s2_lower = s2.downcase
38
-
39
- return s2_lower.length if s1_lower.empty?
40
- return s1_lower.length if s2_lower.empty?
41
-
42
- # Create distance matrix
43
- d = Array.new(s1_lower.length + 1) { Array.new(s2_lower.length + 1) }
44
-
45
- (0..s1_lower.length).each { |i| d[i][0] = i }
46
- (0..s2_lower.length).each { |j| d[0][j] = j }
47
-
48
- (1..s1_lower.length).each do |i|
49
- (1..s2_lower.length).each do |j|
50
- cost = s1_lower[i - 1] == s2_lower[j - 1] ? 0 : 1
51
-
52
- d[i][j] = [
53
- d[i - 1][j] + 1, # deletion
54
- d[i][j - 1] + 1, # insertion
55
- d[i - 1][j - 1] + cost # substitution
56
- ].min
57
- end
58
- end
59
-
60
- d[s1_lower.length][s2_lower.length]
61
- end
62
-
63
- # Generate character n-grams from string
64
- def generate_ngrams(str, n)
65
- return {} if str.length < n
66
-
67
- ngrams = Hash.new(0)
68
- (0..str.length - n).each do |i|
69
- ngrams[str[i, n]] += 1
70
- end
71
- ngrams
72
- end
73
- end
74
- @@Rank = Hash.new { |h,k| h[k] = Rank.new(k) }
75
- class Rank
76
- attr_accessor :data
77
- def initialize k
78
- @id = k
79
- @data = []
80
- end
81
- def << i
82
- @data << i
83
- end
84
- def [] k
85
- KNN.new(@data.to_a).rank(@id, k, 5)
86
- end
87
- end
88
- def self.[] k
89
- @@Rank[k]
90
- end
91
- end
92
- end
data/lib/pedicab/rank.rb~ DELETED
@@ -1,89 +0,0 @@
1
- module Pedicab
2
- module RANK
3
- class KNN
4
- # Initialize with a collection of strings
5
- def initialize(strings)
6
- @strings = strings
7
- end
8
-
9
- # Find k nearest neighbors to the query string
10
- # Returns array of hashes with :string, :distance, and :similarity
11
- def rank(id, query, k = 5, method: :levenshtein)
12
- return [] if @strings.empty?
13
-
14
- # Calculate distances for all strings
15
- distances = @strings.map do |str|
16
- dist = levenshtein_distance(query, str)
17
- {
18
- book: id,
19
- string: str,
20
- distance: dist,
21
- similarity: 1.0 / (1.0 + dist)
22
- }
23
- end
24
-
25
- # Sort by distance (ascending) and take k nearest
26
- distances.sort_by { |d| d[:distance] }.take([k, @strings.length].min)
27
- end
28
-
29
- private
30
-
31
- # Calculate Levenshtein distance between two strings
32
- def levenshtein_distance(s1, s2)
33
- s1_lower = s1.downcase
34
- s2_lower = s2.downcase
35
-
36
- return s2_lower.length if s1_lower.empty?
37
- return s1_lower.length if s2_lower.empty?
38
-
39
- # Create distance matrix
40
- d = Array.new(s1_lower.length + 1) { Array.new(s2_lower.length + 1) }
41
-
42
- (0..s1_lower.length).each { |i| d[i][0] = i }
43
- (0..s2_lower.length).each { |j| d[0][j] = j }
44
-
45
- (1..s1_lower.length).each do |i|
46
- (1..s2_lower.length).each do |j|
47
- cost = s1_lower[i - 1] == s2_lower[j - 1] ? 0 : 1
48
-
49
- d[i][j] = [
50
- d[i - 1][j] + 1, # deletion
51
- d[i][j - 1] + 1, # insertion
52
- d[i - 1][j - 1] + cost # substitution
53
- ].min
54
- end
55
- end
56
-
57
- d[s1_lower.length][s2_lower.length]
58
- end
59
-
60
- # Generate character n-grams from string
61
- def generate_ngrams(str, n)
62
- return {} if str.length < n
63
-
64
- ngrams = Hash.new(0)
65
- (0..str.length - n).each do |i|
66
- ngrams[str[i, n]] += 1
67
- end
68
- ngrams
69
- end
70
- end
71
- @@Rank = Hash.new { |h,k| h[k] = Rank.new(k) }
72
- class Rank
73
- attr_accessor :data, :outline
74
- def initialize k
75
- @id = k
76
- @data = []
77
- end
78
- def << i
79
- @data << i
80
- end
81
- def [] k
82
- KNN.new(@data.to_a).rank(@id, k, 3)
83
- end
84
- end
85
- def self.[] k
86
- @@Rank[k]
87
- end
88
- end
89
- end
data/lib/pedicab/ride.rb~ DELETED
@@ -1,101 +0,0 @@
1
- module Pedicab
2
- @@Ride = Hash.new { |h,k| h[k] = Ride.new(k) }
3
- class Ride
4
- attr_accessor :state, :action, :goal, :ride, :info, :tale, :path, :model
5
- def initialize k
6
- @id = k
7
- @tale = 3
8
- @model = 'model'
9
- reset!
10
- end
11
- def reset!
12
- @state = {}
13
- @ride = []
14
- @path = []
15
- @info = ""
16
- end
17
-
18
- ##
19
- # tell the "tale" of the ride.
20
- def tale
21
- a = []
22
- if @ride.length > 0
23
- h = @ride[-1]
24
- return %[#{h[:input]}\n#{h[:output]}\n]
25
- else
26
- return ""
27
- end
28
- end
29
-
30
- ##
31
- # process input.
32
- def go i
33
- @path << "go #{i}"
34
- @state[:action] = "go"
35
- @state[:input] = i
36
- Pedicab.on[:work].call(self)
37
- @state[:output] = rider(role: 'user', model: 'planner', content: "#{@info}#{tale}#{i}")
38
- @ride << @state
39
- @state[:output].gsub(/\n+/, "\n")
40
- end
41
-
42
- ##
43
- # process condition
44
- def go? i
45
- @path << "go? #{i}"
46
- @state[:action] = "go?"
47
- @state[:input] = i
48
- @state[:yes] = false
49
- Pedicab.on[:gate].call(self)
50
- if rider(role: 'system', model: 'model', content: %[#{@info}#{tale}if the following statement is true respond 'yes', otherwise respond 'no':\n#{i}], response: 'bool' ) == 'yes'
51
- @state[:yes] = true
52
- Pedicab.on[:go].call(self)
53
- end
54
- @ride << @state
55
- @state[:yes]
56
- end
57
-
58
- ##
59
- # process list
60
- def go! i, p, &b
61
- @path << "with #{i} of #{p}"
62
- @state[:action] = "go! fork"
63
- @state[:input] = %[#{@info}#{tale}List only #{i} without repeating yourself:\n#{p}]
64
- Pedicab.on[:fork].call(self)
65
- @state[:list] = rider(role: 'user', model: 'model', content: @state[:input]).split("\n").uniq.map { |e| if e.strip.length > 0; puts %[#[fork]>]; Pedicab.on[:with].call(self); b.call(e.strip); end; }
66
- @ride << @state
67
- @state[:list]
68
- end
69
-
70
- private
71
-
72
- def rider h={}, &b
73
- @state[:content] = "I don't know."
74
- puts %[#====[ #{@ride.length} ][#{@state[:action]}]\n#{@state[:input]}]
75
- Pedicab.on[:before].call(self)
76
- @state[:took] = Benchmark.realtime do
77
- Open3.popen3("sudo python3 bin/pedicab.py /models/#{h[:model]}.gguf") do |stdin, stdout, stderr, wait_thread|
78
- x = lambda { stdin.puts(JSON.generate(h)); stdout.gets }
79
- begin
80
- xx = x.call()
81
- if "#{xx}".strip.length > 0
82
- @state[:content] = JSON.parse("#{xx}")['content']
83
- end
84
- rescue => e
85
- @state[:content] = "Error: #{e}"
86
- end
87
- end
88
- end
89
- Pedicab.on[:after].call(self)
90
- puts %[#====[ #{@ride.length} ] took: #{@state[:took]} seconds.\n#{@state[:content]}\n##{Array.new(80,'=').join('')}#]
91
- if block_given?
92
- return b.call(self).gsub(/\n+/, "\n")
93
- else
94
- return @state[:content].gsub(/\n+/, "\n")
95
- end
96
- end
97
- end
98
- def self.ride
99
- @@Ride
100
- end
101
- end
data/lib/pedicab.sh~ DELETED
@@ -1,3 +0,0 @@
1
- #!/bin/bash
2
-
3
- python3 /usr/bin/pedicab/pedicab.py