pwn 0.5.757 → 0.5.758
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/pwn/ai/ollama.rb +80 -5
- data/lib/pwn/ai/open_web_ui.rb +80 -5
- data/lib/pwn/version.rb +1 -1
- data/spec/lib/pwn/ai/ollama_spec.rb +2 -1
- data/spec/lib/pwn/ai/ollama_system_message_spec.rb +52 -0
- data/spec/lib/pwn/ai/open_web_ui_spec.rb +29 -1
- data/third_party/pwn_rdoc.jsonl +2 -0
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 004ad4f77955698492a48591db3dad3f54d141fb94ddb7952211e86dc4945526
|
|
4
|
+
data.tar.gz: 5c76e0a2f71fdc1afd13f8af828c2027cb8183f3e73612d81f220b864b6df636
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ffe44c731211488e5d07938e29dc1c503307801de30d0c2effc55d139d0f00b0a40a7deeda375f05b581ea88e379b9b82f031b589236bd5a08edd590078b3511
|
|
7
|
+
data.tar.gz: 9c8275fd41e044aed262bcbe7fcf9fe00694b43227030ba1ce90d907c6e68b54efa53dacd3c3cb712890acc159005f5ecd4c9cf1caf065de8032cfc4123041de
|
data/lib/pwn/ai/ollama.rb
CHANGED
|
@@ -436,6 +436,9 @@ module PWN
|
|
|
436
436
|
# - function.arguments must be a Hash/Array object, not a JSON string
|
|
437
437
|
# (string args → HTTP 400 "can't find closing '}' symbol")
|
|
438
438
|
# - assistant content nil + tool_calls → "" (Open WebUI form validation)
|
|
439
|
+
# - system/developer rows after the first message are merged into one
|
|
440
|
+
# leading system message. Qwen-style templates raise HTTP 500
|
|
441
|
+
# "System message must be at the beginning" otherwise.
|
|
439
442
|
private_class_method def self.parse_tool_arguments_object(opts = {})
|
|
440
443
|
raw = opts[:arguments]
|
|
441
444
|
case raw
|
|
@@ -458,7 +461,7 @@ module PWN
|
|
|
458
461
|
end
|
|
459
462
|
|
|
460
463
|
private_class_method def self.normalize_messages_for_ollama(opts = {})
|
|
461
|
-
Array(opts[:messages]).filter_map do |m|
|
|
464
|
+
rows = Array(opts[:messages]).filter_map do |m|
|
|
462
465
|
next unless m.is_a?(Hash)
|
|
463
466
|
|
|
464
467
|
role = (m[:role] || m['role']).to_s
|
|
@@ -508,6 +511,71 @@ module PWN
|
|
|
508
511
|
|
|
509
512
|
out
|
|
510
513
|
end
|
|
514
|
+
lead_system(messages: rows, fold_into_user: opts[:fold_into_user])
|
|
515
|
+
end
|
|
516
|
+
|
|
517
|
+
# One system role is only safe when the server does not already prepend one.
|
|
518
|
+
# Models whose template raises "System message must be at the beginning"
|
|
519
|
+
# already carry a Modelfile SYSTEM prompt. Fold client system text into
|
|
520
|
+
# the first user message instead of sending a second system role.
|
|
521
|
+
private_class_method def self.lead_system(opts = {})
|
|
522
|
+
parts = []
|
|
523
|
+
rest = []
|
|
524
|
+
Array(opts[:messages]).each do |row|
|
|
525
|
+
next unless row.is_a?(Hash)
|
|
526
|
+
|
|
527
|
+
role = (row[:role] || row['role']).to_s
|
|
528
|
+
if %w[system developer].include?(role)
|
|
529
|
+
text = (row.key?(:content) ? row[:content] : row['content']).to_s
|
|
530
|
+
parts << text unless text.strip.empty?
|
|
531
|
+
else
|
|
532
|
+
rest << row
|
|
533
|
+
end
|
|
534
|
+
end
|
|
535
|
+
return rest if parts.empty?
|
|
536
|
+
|
|
537
|
+
text = parts.join("\n\n")
|
|
538
|
+
return [{ role: 'system', content: text }] + rest unless opts[:fold_into_user]
|
|
539
|
+
|
|
540
|
+
user = rest.find { |row| (row[:role] || row['role']).to_s == 'user' }
|
|
541
|
+
if user
|
|
542
|
+
body = (user.key?(:content) ? user[:content] : user['content']).to_s
|
|
543
|
+
user[:content] = "#{text}\n\n#{body}"
|
|
544
|
+
user.delete('content')
|
|
545
|
+
rest
|
|
546
|
+
else
|
|
547
|
+
[{ role: 'user', content: text }] + rest
|
|
548
|
+
end
|
|
549
|
+
end
|
|
550
|
+
|
|
551
|
+
private_class_method def self.strict_system_template?(opts = {})
|
|
552
|
+
name = opts[:model].to_s.strip
|
|
553
|
+
return false if name.empty?
|
|
554
|
+
|
|
555
|
+
@strict_system_cache ||= {}
|
|
556
|
+
return @strict_system_cache[name] if @strict_system_cache.key?(name)
|
|
557
|
+
|
|
558
|
+
@strict_system_cache[name] = template_rejects_later_system?(model: name)
|
|
559
|
+
rescue StandardError
|
|
560
|
+
false
|
|
561
|
+
end
|
|
562
|
+
|
|
563
|
+
private_class_method def self.template_rejects_later_system?(opts = {})
|
|
564
|
+
name = opts[:model].to_s
|
|
565
|
+
names = [name]
|
|
566
|
+
names << "#{name}:latest" unless name.include?(':')
|
|
567
|
+
names.each do |candidate|
|
|
568
|
+
raw = ollama_rest_call(
|
|
569
|
+
http_method: :post, rest_call: 'api/show',
|
|
570
|
+
http_body: { model: candidate }, timeout: 8, quiet: true, non_interactive: true
|
|
571
|
+
)
|
|
572
|
+
template = PWN::AI::ModelCatalog.parse_row(raw: raw)
|
|
573
|
+
text = template.is_a?(Hash) ? (template[:template] || template['template']).to_s : ''
|
|
574
|
+
return true if text.include?('System message must be at the beginning')
|
|
575
|
+
end
|
|
576
|
+
false
|
|
577
|
+
rescue StandardError
|
|
578
|
+
false
|
|
511
579
|
end
|
|
512
580
|
|
|
513
581
|
# Supported Method Parameters::
|
|
@@ -526,13 +594,16 @@ module PWN
|
|
|
526
594
|
# NDJSON chunks back into a single response.
|
|
527
595
|
|
|
528
596
|
public_class_method def self.chat_with_tools(opts = {})
|
|
529
|
-
engine
|
|
530
|
-
messages = normalize_messages_for_ollama(messages: opts[:messages])
|
|
531
|
-
raise 'ERROR: messages array is required' if messages.nil? || messages.empty?
|
|
532
|
-
|
|
597
|
+
engine = PWN::Env[:ai][:ollama]
|
|
533
598
|
model = opts[:model] ||= engine[:model]
|
|
534
599
|
raise 'ERROR: Model is required. Call #get_models method for details' if model.nil?
|
|
535
600
|
|
|
601
|
+
messages = normalize_messages_for_ollama(
|
|
602
|
+
messages: opts[:messages],
|
|
603
|
+
fold_into_user: strict_system_template?(model: model)
|
|
604
|
+
)
|
|
605
|
+
raise 'ERROR: messages array is required' if messages.nil? || messages.empty?
|
|
606
|
+
|
|
536
607
|
temp = opts[:temp].to_f
|
|
537
608
|
temp = engine[:temp].to_f.nonzero? || 1 if temp.zero?
|
|
538
609
|
|
|
@@ -656,6 +727,10 @@ module PWN
|
|
|
656
727
|
end
|
|
657
728
|
|
|
658
729
|
http_body[:messages].push(user_role)
|
|
730
|
+
http_body[:messages] = lead_system(
|
|
731
|
+
messages: http_body[:messages],
|
|
732
|
+
fold_into_user: strict_system_template?(model: model)
|
|
733
|
+
)
|
|
659
734
|
|
|
660
735
|
timeout = opts[:timeout]
|
|
661
736
|
spinner = opts[:spinner]
|
data/lib/pwn/ai/open_web_ui.rb
CHANGED
|
@@ -468,6 +468,9 @@ module PWN
|
|
|
468
468
|
# - function.arguments must be a Hash/Array object, not a JSON string
|
|
469
469
|
# (string args → HTTP 400 "can't find closing '}' symbol")
|
|
470
470
|
# - assistant content nil + tool_calls → "" (Open WebUI form validation)
|
|
471
|
+
# - system/developer rows after the first message are merged into one
|
|
472
|
+
# leading system message. Qwen-style templates raise HTTP 500
|
|
473
|
+
# "System message must be at the beginning" otherwise.
|
|
471
474
|
private_class_method def self.parse_tool_arguments_object(opts = {})
|
|
472
475
|
raw = opts[:arguments]
|
|
473
476
|
case raw
|
|
@@ -490,7 +493,7 @@ module PWN
|
|
|
490
493
|
end
|
|
491
494
|
|
|
492
495
|
private_class_method def self.normalize_messages_for_ollama(opts = {})
|
|
493
|
-
Array(opts[:messages]).filter_map do |m|
|
|
496
|
+
rows = Array(opts[:messages]).filter_map do |m|
|
|
494
497
|
next unless m.is_a?(Hash)
|
|
495
498
|
|
|
496
499
|
role = (m[:role] || m['role']).to_s
|
|
@@ -540,6 +543,71 @@ module PWN
|
|
|
540
543
|
|
|
541
544
|
out
|
|
542
545
|
end
|
|
546
|
+
lead_system(messages: rows, fold_into_user: opts[:fold_into_user])
|
|
547
|
+
end
|
|
548
|
+
|
|
549
|
+
# One system role is only safe when the server does not already prepend one.
|
|
550
|
+
# mini-mythos-mission-ready has a Modelfile SYSTEM prompt and a template that
|
|
551
|
+
# raises if any later message has role system. Fold those rows into the
|
|
552
|
+
# first user message instead of sending a second system role.
|
|
553
|
+
private_class_method def self.lead_system(opts = {})
|
|
554
|
+
parts = []
|
|
555
|
+
rest = []
|
|
556
|
+
Array(opts[:messages]).each do |row|
|
|
557
|
+
next unless row.is_a?(Hash)
|
|
558
|
+
|
|
559
|
+
role = (row[:role] || row['role']).to_s
|
|
560
|
+
if %w[system developer].include?(role)
|
|
561
|
+
text = (row.key?(:content) ? row[:content] : row['content']).to_s
|
|
562
|
+
parts << text unless text.strip.empty?
|
|
563
|
+
else
|
|
564
|
+
rest << row
|
|
565
|
+
end
|
|
566
|
+
end
|
|
567
|
+
return rest if parts.empty?
|
|
568
|
+
|
|
569
|
+
text = parts.join("\n\n")
|
|
570
|
+
return [{ role: 'system', content: text }] + rest unless opts[:fold_into_user]
|
|
571
|
+
|
|
572
|
+
user = rest.find { |row| (row[:role] || row['role']).to_s == 'user' }
|
|
573
|
+
if user
|
|
574
|
+
body = (user.key?(:content) ? user[:content] : user['content']).to_s
|
|
575
|
+
user[:content] = "#{text}\n\n#{body}"
|
|
576
|
+
user.delete('content')
|
|
577
|
+
rest
|
|
578
|
+
else
|
|
579
|
+
[{ role: 'user', content: text }] + rest
|
|
580
|
+
end
|
|
581
|
+
end
|
|
582
|
+
|
|
583
|
+
private_class_method def self.strict_system_template?(opts = {})
|
|
584
|
+
name = opts[:model].to_s.strip
|
|
585
|
+
return false if name.empty?
|
|
586
|
+
|
|
587
|
+
@strict_system_cache ||= {}
|
|
588
|
+
return @strict_system_cache[name] if @strict_system_cache.key?(name)
|
|
589
|
+
|
|
590
|
+
@strict_system_cache[name] = template_rejects_later_system?(model: name)
|
|
591
|
+
rescue StandardError
|
|
592
|
+
false
|
|
593
|
+
end
|
|
594
|
+
|
|
595
|
+
private_class_method def self.template_rejects_later_system?(opts = {})
|
|
596
|
+
name = opts[:model].to_s
|
|
597
|
+
names = [name]
|
|
598
|
+
names << "#{name}:latest" unless name.include?(':')
|
|
599
|
+
names.each do |candidate|
|
|
600
|
+
raw = openwebui_rest_call(
|
|
601
|
+
http_method: :post, rest_call: 'ollama/api/show',
|
|
602
|
+
http_body: { model: candidate }, timeout: 8, quiet: true, non_interactive: true
|
|
603
|
+
)
|
|
604
|
+
template = PWN::AI::ModelCatalog.parse_row(raw: raw)
|
|
605
|
+
text = template.is_a?(Hash) ? (template[:template] || template['template']).to_s : ''
|
|
606
|
+
return true if text.include?('System message must be at the beginning')
|
|
607
|
+
end
|
|
608
|
+
false
|
|
609
|
+
rescue StandardError
|
|
610
|
+
false
|
|
543
611
|
end
|
|
544
612
|
|
|
545
613
|
# Supported Method Parameters::
|
|
@@ -559,13 +627,16 @@ module PWN
|
|
|
559
627
|
# Bare POST /api/chat is not an API route on stock Open WebUI (405).
|
|
560
628
|
|
|
561
629
|
public_class_method def self.chat_with_tools(opts = {})
|
|
562
|
-
engine
|
|
563
|
-
messages = normalize_messages_for_ollama(messages: opts[:messages])
|
|
564
|
-
raise 'ERROR: messages array is required' if messages.nil? || messages.empty?
|
|
565
|
-
|
|
630
|
+
engine = PWN::Env[:ai][:openwebui]
|
|
566
631
|
model = opts[:model] ||= engine[:model]
|
|
567
632
|
raise 'ERROR: Model is required. Call #get_models method for details' unless real_config_value?(value: model)
|
|
568
633
|
|
|
634
|
+
messages = normalize_messages_for_ollama(
|
|
635
|
+
messages: opts[:messages],
|
|
636
|
+
fold_into_user: strict_system_template?(model: model)
|
|
637
|
+
)
|
|
638
|
+
raise 'ERROR: messages array is required' if messages.nil? || messages.empty?
|
|
639
|
+
|
|
569
640
|
temp = opts[:temp].to_f
|
|
570
641
|
temp = engine[:temp].to_f.nonzero? || 1 if temp.zero?
|
|
571
642
|
|
|
@@ -682,6 +753,10 @@ module PWN
|
|
|
682
753
|
end
|
|
683
754
|
|
|
684
755
|
http_body[:messages].push(user_role)
|
|
756
|
+
http_body[:messages] = lead_system(
|
|
757
|
+
messages: http_body[:messages],
|
|
758
|
+
fold_into_user: strict_system_template?(model: model)
|
|
759
|
+
)
|
|
685
760
|
|
|
686
761
|
timeout = opts[:timeout]
|
|
687
762
|
spinner = opts[:spinner]
|
data/lib/pwn/version.rb
CHANGED
|
@@ -12,10 +12,11 @@ describe PWN::AI::Ollama do
|
|
|
12
12
|
allow(described_class).to receive(:sleep)
|
|
13
13
|
allow(described_class).to receive(:rand).and_return(0.5)
|
|
14
14
|
allow(PWN::AI::HttpRetry).to receive(:report_event)
|
|
15
|
+
described_class.instance_variable_set(:@strict_system_cache, nil)
|
|
15
16
|
expect do
|
|
16
17
|
described_class.chat_with_tools(messages: [{ role: 'user', content: 'hello' }], quiet: quiet)
|
|
17
18
|
end.to raise_error(RuntimeError, /Ollama.*429.*rate limit exceeded/)
|
|
18
|
-
expect(RestClient::Request).to have_received(:execute).exactly(
|
|
19
|
+
expect(RestClient::Request).to have_received(:execute).exactly(6).times
|
|
19
20
|
expect(described_class).to have_received(:sleep).with(2.5).exactly(4).times
|
|
20
21
|
end
|
|
21
22
|
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
describe 'Ollama and Open WebUI system-message placement' do
|
|
6
|
+
it 'puts a later Ollama system message first so the chat template does not 500' do
|
|
7
|
+
engine = { model: 'mini-mythos-mission-ready', num_ctx: 2048, keep_alive: '1m', temp: 0.1, tool_temp: 0.1 }
|
|
8
|
+
allow(PWN::Env).to receive(:[]).and_call_original
|
|
9
|
+
allow(PWN::Env).to receive(:[]).with(:ai).and_return({ ollama: engine, active: 'ollama' })
|
|
10
|
+
captured = nil
|
|
11
|
+
allow(PWN::AI::Ollama).to receive(:ollama_rest_call) do |**kwargs|
|
|
12
|
+
captured = kwargs[:http_body]
|
|
13
|
+
'{"message":{"role":"assistant","content":"ok"}}'
|
|
14
|
+
end
|
|
15
|
+
PWN::AI::Ollama.chat_with_tools(
|
|
16
|
+
model: 'mini-mythos-mission-ready',
|
|
17
|
+
messages: [
|
|
18
|
+
{ role: 'user', content: 'hello' },
|
|
19
|
+
{ role: 'system', content: 'must lead' },
|
|
20
|
+
{ role: 'developer', content: 'also lead' }
|
|
21
|
+
]
|
|
22
|
+
)
|
|
23
|
+
expect(captured[:messages].map { |row| row[:role] }).to eq(%w[system user])
|
|
24
|
+
expect(captured[:messages][0][:content]).to include('must lead', 'also lead')
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it 'folds Open WebUI system text into the user message when the template rejects a second system role' do
|
|
28
|
+
engine = { model: 'mini-mythos-mission-ready:latest', num_ctx: 2048, keep_alive: '1m', temp: 0.1, tool_temp: 0.1 }
|
|
29
|
+
allow(PWN::Env).to receive(:[]).and_call_original
|
|
30
|
+
allow(PWN::Env).to receive(:[]).with(:ai).and_return({ openwebui: engine, active: 'openwebui' })
|
|
31
|
+
PWN::AI::OpenWebUI.instance_variable_set(:@strict_system_cache, nil)
|
|
32
|
+
captured = nil
|
|
33
|
+
allow(PWN::AI::OpenWebUI).to receive(:openwebui_rest_call) do |**kwargs|
|
|
34
|
+
if kwargs[:rest_call].to_s.end_with?('show')
|
|
35
|
+
{ template: "raise_exception('System message must be at the beginning.')" }.to_json
|
|
36
|
+
else
|
|
37
|
+
captured = kwargs[:http_body]
|
|
38
|
+
'{"message":{"role":"assistant","content":"ok"}}'
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
PWN::AI::OpenWebUI.chat_with_tools(
|
|
42
|
+
model: 'mini-mythos-mission-ready:latest',
|
|
43
|
+
messages: [
|
|
44
|
+
{ role: 'system', content: 'operator rules' },
|
|
45
|
+
{ role: 'user', content: 'ping' },
|
|
46
|
+
{ role: 'system', content: 'ENGAGEMENT MEMORY' }
|
|
47
|
+
]
|
|
48
|
+
)
|
|
49
|
+
expect(captured[:messages].map { |row| row[:role] }).to eq(%w[user])
|
|
50
|
+
expect(captured[:messages][0][:content]).to include('operator rules', 'ENGAGEMENT MEMORY', 'ping')
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -12,10 +12,11 @@ describe PWN::AI::OpenWebUI do
|
|
|
12
12
|
allow(described_class).to receive(:sleep)
|
|
13
13
|
allow(described_class).to receive(:rand).and_return(0.5)
|
|
14
14
|
allow(PWN::AI::HttpRetry).to receive(:report_event)
|
|
15
|
+
described_class.instance_variable_set(:@strict_system_cache, nil)
|
|
15
16
|
expect do
|
|
16
17
|
described_class.chat_with_tools(messages: [{ role: 'user', content: 'hello' }], quiet: quiet)
|
|
17
18
|
end.to raise_error(RuntimeError, /Open WebUI.*429.*rate limit exceeded/)
|
|
18
|
-
expect(RestClient::Request).to have_received(:execute).exactly(
|
|
19
|
+
expect(RestClient::Request).to have_received(:execute).exactly(6).times
|
|
19
20
|
expect(described_class).to have_received(:sleep).with(2.5).exactly(4).times
|
|
20
21
|
end
|
|
21
22
|
end
|
|
@@ -83,6 +84,33 @@ describe PWN::AI::OpenWebUI do
|
|
|
83
84
|
expect(captured_chat[:stream]).to be true
|
|
84
85
|
end
|
|
85
86
|
|
|
87
|
+
it 'merges later system and developer messages into one leading system message' do
|
|
88
|
+
engine = { model: 'mini-mythos-mission-ready', num_ctx: 2048, keep_alive: '1m', temp: 0.1, tool_temp: 0.1 }
|
|
89
|
+
allow(PWN::Env).to receive(:[]).and_call_original
|
|
90
|
+
allow(PWN::Env).to receive(:[]).with(:ai).and_return({ openwebui: engine, active: 'openwebui' })
|
|
91
|
+
captured = nil
|
|
92
|
+
allow(described_class).to receive(:openwebui_rest_call) do |**kwargs|
|
|
93
|
+
captured = kwargs[:http_body]
|
|
94
|
+
'{"message":{"role":"assistant","content":"ok"}}'
|
|
95
|
+
end
|
|
96
|
+
described_class.chat_with_tools(
|
|
97
|
+
messages: [
|
|
98
|
+
{ role: 'system', content: 'operator rules' },
|
|
99
|
+
{ role: 'user', content: 'hello' },
|
|
100
|
+
{ role: 'system', content: 'ENGAGEMENT MEMORY\nnotes' },
|
|
101
|
+
{ role: 'developer', content: 'mid-turn reminder' },
|
|
102
|
+
{ role: 'assistant', content: '', tool_calls: [{ id: 'c1', type: 'function', function: { name: 'shell', arguments: '{"cmd":"id"}' } }] }
|
|
103
|
+
],
|
|
104
|
+
model: 'mini-mythos-mission-ready'
|
|
105
|
+
)
|
|
106
|
+
roles = captured[:messages].map { |row| row[:role] }
|
|
107
|
+
expect(roles).to eq(%w[system user assistant])
|
|
108
|
+
expect(captured[:messages][0][:content]).to include('operator rules')
|
|
109
|
+
expect(captured[:messages][0][:content]).to include('ENGAGEMENT MEMORY')
|
|
110
|
+
expect(captured[:messages][0][:content]).to include('mid-turn reminder')
|
|
111
|
+
expect(captured[:messages][2][:tool_calls].first[:function][:arguments]).to eq({ cmd: 'id' })
|
|
112
|
+
end
|
|
113
|
+
|
|
86
114
|
it 'assembles native /api/chat NDJSON stream into a single message' do
|
|
87
115
|
body = [
|
|
88
116
|
{ model: 'm', message: { role: 'assistant', content: 'Hel' }, done: false }.to_json,
|
data/third_party/pwn_rdoc.jsonl
CHANGED
|
@@ -1201,6 +1201,7 @@
|
|
|
1201
1201
|
{"messages":[{"role":"user","content":"PWN::AI::Ollama.get_model Usage"},{"role":"assistant","content":"`PWN::AI::Ollama.get_model`: Supported Method Parameters\n\nmodel = PWN::AI::Ollama.get_model(name: ‘required - tag name’)\n\nLocal tags have size and family, not token prices. get_model reads /api/show for that tag and returns it. Missing pricing stays missing.\n"}]}
|
|
1202
1202
|
{"messages":[{"role":"user","content":"PWN::AI::Ollama.get_models Usage"},{"role":"assistant","content":"`PWN::AI::Ollama.get_models`: Supported Method Parameters\n\nresponse = PWN::AI::Ollama.get_models\n"}]}
|
|
1203
1203
|
{"messages":[{"role":"user","content":"PWN::AI::Ollama.help Usage"},{"role":"assistant","content":"`PWN::AI::Ollama.help`: "}]}
|
|
1204
|
+
{"messages":[{"role":"user","content":"PWN::AI::Ollama.lead_system Usage"},{"role":"assistant","content":"`PWN::AI::Ollama.lead_system`: "}]}
|
|
1204
1205
|
{"messages":[{"role":"user","content":"PWN::AI::Ollama.normalize_messages_for_ollama Usage"},{"role":"assistant","content":"`PWN::AI::Ollama.normalize_messages_for_ollama`: "}]}
|
|
1205
1206
|
{"messages":[{"role":"user","content":"PWN::AI::Ollama.ollama_rest_call Usage"},{"role":"assistant","content":"`PWN::AI::Ollama.ollama_rest_call`: Supported Method Parameters\n\nollama_rest_call(\n\nhttp_method: 'optional HTTP method (defaults to GET)',\nrest_call: 'required rest call path relative to base_uri (e.g. api/chat)',\nparams: 'optional params passed in the URI or HTTP Headers',\nhttp_body: 'optional HTTP body sent in HTTP methods that support it e.g. POST',\ntimeout: 'optional timeout in seconds (defaults to 900)',\nspinner: 'optional - display spinner (defaults to false)'\n\n)\n"}]}
|
|
1206
1207
|
{"messages":[{"role":"user","content":"PWN::AI::Ollama.parse_tool_arguments_object Usage"},{"role":"assistant","content":"`PWN::AI::Ollama.parse_tool_arguments_object`: "}]}
|
|
@@ -1252,6 +1253,7 @@
|
|
|
1252
1253
|
{"messages":[{"role":"user","content":"PWN::AI::OpenWebUI.get_model Usage"},{"role":"assistant","content":"`PWN::AI::OpenWebUI.get_model`: Supported Method Parameters\n\nmodel = PWN::AI::OpenWebUI.get_model(name: ‘required - model id’)\n\nOpen WebUI mixes OpenAI-compat rows and proxied Ollama tags. A direct model route is tried first; otherwise the already-fetched catalog row is returned. Local tags without a price stay unpriced.\n"}]}
|
|
1253
1254
|
{"messages":[{"role":"user","content":"PWN::AI::OpenWebUI.get_models Usage"},{"role":"assistant","content":"`PWN::AI::OpenWebUI.get_models`: Supported Method Parameters\n\nresponse = PWN::AI::OpenWebUI.get_models\n"}]}
|
|
1254
1255
|
{"messages":[{"role":"user","content":"PWN::AI::OpenWebUI.help Usage"},{"role":"assistant","content":"`PWN::AI::OpenWebUI.help`: "}]}
|
|
1256
|
+
{"messages":[{"role":"user","content":"PWN::AI::OpenWebUI.lead_system Usage"},{"role":"assistant","content":"`PWN::AI::OpenWebUI.lead_system`: "}]}
|
|
1255
1257
|
{"messages":[{"role":"user","content":"PWN::AI::OpenWebUI.normalize_messages_for_ollama Usage"},{"role":"assistant","content":"`PWN::AI::OpenWebUI.normalize_messages_for_ollama`: "}]}
|
|
1256
1258
|
{"messages":[{"role":"user","content":"PWN::AI::OpenWebUI.openwebui_rest_call Usage"},{"role":"assistant","content":"`PWN::AI::OpenWebUI.openwebui_rest_call`: Supported Method Parameters\n\nopenwebui_rest_call(\n\nhttp_method: 'optional HTTP method (defaults to GET)',\nrest_call: 'required rest call path relative to base_uri',\nparams: 'optional params passed in the URI or HTTP Headers',\nhttp_body: 'optional HTTP body sent in HTTP methods that support it e.g. POST',\ntimeout: 'optional timeout in seconds (defaults to 900)',\nspinner: 'optional - display spinner (defaults to false)'\n\n)\n"}]}
|
|
1257
1259
|
{"messages":[{"role":"user","content":"PWN::AI::OpenWebUI.parse_tool_arguments_object Usage"},{"role":"assistant","content":"`PWN::AI::OpenWebUI.parse_tool_arguments_object`: "}]}
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: pwn
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.5.
|
|
4
|
+
version: 0.5.758
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- 0day Inc.
|
|
@@ -6754,6 +6754,7 @@ files:
|
|
|
6754
6754
|
- spec/lib/pwn/ai/model_catalog_spec.rb
|
|
6755
6755
|
- spec/lib/pwn/ai/model_lookup_spec.rb
|
|
6756
6756
|
- spec/lib/pwn/ai/ollama_spec.rb
|
|
6757
|
+
- spec/lib/pwn/ai/ollama_system_message_spec.rb
|
|
6757
6758
|
- spec/lib/pwn/ai/open_ai_oauth_transport_spec.rb
|
|
6758
6759
|
- spec/lib/pwn/ai/open_ai_spec.rb
|
|
6759
6760
|
- spec/lib/pwn/ai/open_web_ui_spec.rb
|