pwn 0.5.782 → 0.5.783
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/documentation/Installation.md +33 -9
- data/documentation/pwn-REPL.md +31 -3
- data/documentation/pwn-ai-Agent.md +62 -2
- data/etc/default_cron/session_cleanup.rb +335 -42
- data/lib/pwn/ai/agent/curriculum.rb +2 -2
- data/lib/pwn/ai/agent/learning.rb +11 -4
- data/lib/pwn/ai/agent/mistakes.rb +22 -3
- data/lib/pwn/ai/agent/tools/sessions.rb +6 -6
- data/lib/pwn/ai/http_retry.rb +3 -0
- data/lib/pwn/ai/router.rb +3 -1
- data/lib/pwn/cron.rb +1 -1
- data/lib/pwn/memory.rb +62 -6
- data/lib/pwn/plugins/repl/ai.rb +13 -3
- data/lib/pwn/plugins/repl/ai_console.rb +37 -21
- data/lib/pwn/session_trace.rb +1 -1
- data/lib/pwn/sessions.rb +305 -80
- data/lib/pwn/version.rb +1 -1
- data/spec/lib/pwn/ai/agent/learning_spec.rb +65 -2
- data/spec/lib/pwn/ai/agent/swarm_spec.rb +3 -3
- data/spec/lib/pwn/memory_spec.rb +58 -1
- data/spec/lib/pwn/plugins/repl/ai_console_spec.rb +191 -6
- data/spec/lib/pwn/plugins/repl/ai_result_chronology_spec.rb +2 -2
- data/spec/lib/pwn/plugins/repl/ai_spec.rb +28 -11
- data/spec/lib/pwn/session_cleanup_default_spec.rb +2 -2
- data/spec/lib/pwn/session_cleanup_payload_spec.rb +467 -36
- data/spec/lib/pwn/sessions_spec.rb +116 -16
- data/third_party/pwn_rdoc.jsonl +12 -0
- metadata +1 -1
|
@@ -7,13 +7,113 @@ require 'fileutils'
|
|
|
7
7
|
describe PWN::Sessions do
|
|
8
8
|
include_context 'pwn tmp sandbox'
|
|
9
9
|
|
|
10
|
+
it 'reconciles page size, filtered inventory and physical support entries' do
|
|
11
|
+
allow(Dir).to receive(:home).and_return(@tmp)
|
|
12
|
+
3.times { described_class.create }
|
|
13
|
+
File.write(File.join(described_class.sessions_dir, 'abandoned.tmp'), 'fixture')
|
|
14
|
+
page = described_class.catalog(limit: 1)
|
|
15
|
+
expect(page).to include(total: 0, physical_sessions: 3, filtered_sessions: 3, returned: 0, has_previous: false)
|
|
16
|
+
expect(page[:storage][:transcripts]).to eq(3)
|
|
17
|
+
expect(page[:storage].values.sum).to eq(Dir.children(described_class.sessions_dir).length)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it 'uses the compact layout while reading legacy metadata and sharing legacy lock inodes' do
|
|
21
|
+
allow(Dir).to receive(:home).and_return(@tmp)
|
|
22
|
+
sid = described_class.create[:id]
|
|
23
|
+
old_meta = File.join(described_class.sessions_dir, "#{sid}.meta.json")
|
|
24
|
+
old_lock = File.join(described_class.sessions_dir, ".#{sid}.cleanup.lock")
|
|
25
|
+
lease = described_class.activate(session_id: sid)
|
|
26
|
+
File.write(File.join(described_class.sessions_dir, '.layout-v2'), '2')
|
|
27
|
+
expect(described_class.metadata(session_id: sid)[:id]).to eq(sid)
|
|
28
|
+
expect(described_class.active?(session_id: sid)).to be(true)
|
|
29
|
+
expect(described_class.support_path(kind: :metadata, session_id: sid)).to eq(old_meta)
|
|
30
|
+
expect(described_class.support_path(kind: :lease, session_id: sid)).to eq(old_lock)
|
|
31
|
+
fresh = described_class.create[:id]
|
|
32
|
+
expect(File.file?(File.join(described_class.sessions_dir, 'support', 'metadata', "#{fresh}.meta.json"))).to be(true)
|
|
33
|
+
expect(described_class.dependency_index[:errors]).to be_empty
|
|
34
|
+
ensure
|
|
35
|
+
described_class.deactivate(lease: lease)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it 'treats complete policy trajectories as self-contained provenance but pins incomplete legacy rows' do
|
|
39
|
+
allow(Dir).to receive(:home).and_return(@tmp)
|
|
40
|
+
FileUtils.mkdir_p(File.join(@tmp, '.pwn'))
|
|
41
|
+
sid = described_class.create[:id]
|
|
42
|
+
trajectory = File.join(@tmp, '.pwn', 'policy_traj.jsonl')
|
|
43
|
+
row = { session_id: sid, request_family: 'ops', kind: 'task', engine: 'fixture', started_at: 'start', ended_at: 'end',
|
|
44
|
+
score: 1.0, verdict: 'success', return: 1.0, attribution: {}, steps: [{ state: 's', action: 'a', reward: 1.0, next_state: 's2', ok: true, duration: 0.1, terminal: true }] }
|
|
45
|
+
File.write(trajectory, "#{JSON.generate(row)}\n")
|
|
46
|
+
expect(described_class.dependency_index[:dependencies].fetch(sid, [])).not_to include(trajectory)
|
|
47
|
+
expect(JSON.parse(File.read(trajectory))['session_id']).to eq(sid)
|
|
48
|
+
legacy = row.except(:request_family, :attribution).merge(request: 'fixture request')
|
|
49
|
+
terminal = row.merge(score: nil, return: nil, steps: [{ state: 's', action: 'final', next_state: 's', reward: 0.0, terminal: true, credit_mode: 'terminal_attribution', credit_eligible: false }])
|
|
50
|
+
File.write(trajectory, [legacy, terminal].map { |record| JSON.generate(record) }.join("\n"))
|
|
51
|
+
expect(described_class.dependency_index[:dependencies].fetch(sid, [])).not_to include(trajectory)
|
|
52
|
+
File.write(trajectory, "#{JSON.generate(session_id: sid)}\n")
|
|
53
|
+
expect(described_class.dependency_index[:dependencies][sid]).to include(trajectory)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
it 'shows the active provisional session without granting summary retention or hiding latest pages' do
|
|
57
|
+
allow(Dir).to receive(:home).and_return(@tmp)
|
|
58
|
+
ids = 4.times.map do |index|
|
|
59
|
+
sid = described_class.create[:id]
|
|
60
|
+
described_class.append(session_id: sid, role: 'user', content: "Fixture topic #{index}")
|
|
61
|
+
allow(PWN::AI::Router).to receive(:summarize).and_return(JSON.generate(title: "Topic #{index}", summary: "Conversation #{index}"))
|
|
62
|
+
described_class.refresh_title(session_id: sid)
|
|
63
|
+
File.utime(Time.at(index), Time.at(index), File.join(described_class.sessions_dir, "#{sid}.jsonl"))
|
|
64
|
+
sid
|
|
65
|
+
end
|
|
66
|
+
active = described_class.create[:id]
|
|
67
|
+
described_class.provisional_title(session_id: active, request: 'Investigate active topic')
|
|
68
|
+
page = described_class.catalog(current_session_id: active, limit: 2)
|
|
69
|
+
expect(page).to include(total: 5, offset: 3, has_more: false)
|
|
70
|
+
expect(page[:sessions].map { |row| row[:id] }).to eq([ids.last, active])
|
|
71
|
+
expect(page[:sessions].last).to include(active: true, title: 'Investigate active topic')
|
|
72
|
+
older = described_class.catalog(current_session_id: active, offset: 0, limit: 2)
|
|
73
|
+
expect(older[:sessions].map { |row| row[:id] }).to eq([*ids.first(2), active])
|
|
74
|
+
expect(older[:has_more]).to be(true)
|
|
75
|
+
expect(described_class.title_status(session_id: active)).to include(is_summarized: false)
|
|
76
|
+
expect(described_class.retention_status(session_id: active)[:visible]).to be(false)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
it 'summarizes the correct session through the captured provider route outside another request scope' do
|
|
80
|
+
allow(Dir).to receive(:home).and_return(@tmp)
|
|
81
|
+
sid = described_class.create[:id]
|
|
82
|
+
other = described_class.create[:id]
|
|
83
|
+
described_class.append(session_id: sid, role: 'user', content: 'Repair login certificate')
|
|
84
|
+
described_class.append(session_id: other, role: 'user', content: 'Unrelated other session')
|
|
85
|
+
config = { active: :openai, openai: { model: 'captured-model', key: 'fixture-key' } }
|
|
86
|
+
PWN::Env[:ai] = { active: :ollama, ollama: { model: 'different-model', base_uri: 'http://fixture.invalid' } }
|
|
87
|
+
previous = Thread.current[:pwn_request_runtime]
|
|
88
|
+
foreign = double('foreign request')
|
|
89
|
+
Thread.current[:pwn_request_runtime] = foreign
|
|
90
|
+
expect(foreign).not_to receive(:provider_config)
|
|
91
|
+
expect(PWN::AI::Ollama).not_to receive(:chat)
|
|
92
|
+
allow(PWN::AI::Router).to receive(:summarize).and_call_original
|
|
93
|
+
expect(PWN::AI::OpenAI).to receive(:open_ai_rest_call) do |opts|
|
|
94
|
+
expect(opts[:http_body][:model]).to eq('captured-model')
|
|
95
|
+
prompt = opts[:http_body][:messages].last[:content]
|
|
96
|
+
expect(prompt).to include('Repair login certificate')
|
|
97
|
+
expect(prompt).not_to include('Unrelated other session')
|
|
98
|
+
JSON.generate(choices: [{ message: { role: 'assistant', content: JSON.generate(title: 'Login certificate recovery', summary: 'Repaired login certificates.') } }])
|
|
99
|
+
end
|
|
100
|
+
result = described_class.refresh_title(session_id: sid, ai_config: config)
|
|
101
|
+
expect(result).to include(title: 'Login certificate recovery', title_source: 'summary', summary_turns: 1)
|
|
102
|
+
expect(Thread.current[:pwn_request_runtime]).to equal(foreign)
|
|
103
|
+
expect(described_class.metadata(session_id: other)[:title_source]).not_to eq('summary')
|
|
104
|
+
ensure
|
|
105
|
+
Thread.current[:pwn_request_runtime] = previous
|
|
106
|
+
end
|
|
107
|
+
|
|
10
108
|
it 'rejects provider echoed placeholder titles without advancing summary provenance' do
|
|
11
109
|
session = described_class.create
|
|
12
110
|
sid = session[:id]
|
|
13
111
|
described_class.append(session_id: sid, role: 'user', content: 'Explain session locking')
|
|
14
112
|
allow(PWN::AI::Router).to receive(:summarize).and_return(JSON.generate(title: "pwn-ai session #{sid}", summary: 'Session locking explained'))
|
|
15
113
|
original = described_class.metadata(session_id: sid)
|
|
16
|
-
|
|
114
|
+
failures = []
|
|
115
|
+
expect(described_class.refresh_title(session_id: sid, on_error: failures.method(:push))).to eq(original)
|
|
116
|
+
expect(failures).to eq(['ArgumentError'])
|
|
17
117
|
expect(described_class.metadata(session_id: sid)).to eq(original)
|
|
18
118
|
end
|
|
19
119
|
|
|
@@ -23,10 +123,10 @@ describe PWN::Sessions do
|
|
|
23
123
|
described_class.create(id: id)
|
|
24
124
|
observer = described_class.create(id: '20260709_172057_49594079')
|
|
25
125
|
25.times do
|
|
26
|
-
listing = JSON.generate(described_class.list)
|
|
126
|
+
listing = JSON.generate(described_class.list(include_hidden: true))
|
|
27
127
|
File.open(observer[:path], 'a') { |file| file.puts(JSON.generate(role: 'tool', content: listing)) }
|
|
28
128
|
end
|
|
29
|
-
result = described_class.list.find { |row| row[:id] == id }
|
|
129
|
+
result = described_class.list(include_hidden: true).find { |row| row[:id] == id }
|
|
30
130
|
expect(result[:dependencies]).to eq([])
|
|
31
131
|
expect(result[:dependency_errors]).to eq([])
|
|
32
132
|
end
|
|
@@ -100,7 +200,7 @@ describe PWN::Sessions do
|
|
|
100
200
|
'artifacts/manifest.jsonl' => { session: "#{sid}.extra", tags: [sid], source_path: "/tmp/#{sid}.jsonl" }
|
|
101
201
|
}
|
|
102
202
|
fixtures.each { |relative, value| dependency_fixture(relative, value) }
|
|
103
|
-
expect(described_class.dependency_index).to eq(dependencies: {}, errors: [])
|
|
203
|
+
expect(described_class.dependency_index).to eq(dependencies: {}, errors: [], session_errors: {}, invalid_records: [])
|
|
104
204
|
end
|
|
105
205
|
|
|
106
206
|
it 'recognizes only exact session-owned paths and exact structured evidence paths' do
|
|
@@ -129,7 +229,7 @@ describe PWN::Sessions do
|
|
|
129
229
|
session = described_class.create(id: sid)
|
|
130
230
|
File.write(session[:path], JSON.generate(role: 'tool', content: { session_id: other }, session_id: other))
|
|
131
231
|
File.write(session[:path].sub('.jsonl', '.meta.json'), JSON.generate(id: sid, title: other, source: other, summary: JSON.generate(session_id: other)))
|
|
132
|
-
expect(described_class.dependency_index).to eq(dependencies: {}, errors: [])
|
|
232
|
+
expect(described_class.dependency_index).to eq(dependencies: {}, errors: [], session_errors: {}, invalid_records: [])
|
|
133
233
|
end
|
|
134
234
|
|
|
135
235
|
it 'reports unknown stores and malformed structural references without guessing' do
|
|
@@ -146,7 +246,7 @@ describe PWN::Sessions do
|
|
|
146
246
|
|
|
147
247
|
it 'does not treat an extensionless session-looking evidence path as a transcript' do
|
|
148
248
|
dependency_fixture('findings.jsonl', { evidence_paths: [File.join(described_class.sessions_dir, sid)] })
|
|
149
|
-
expect(described_class.dependency_index).to eq(dependencies: {}, errors: [])
|
|
249
|
+
expect(described_class.dependency_index).to eq(dependencies: {}, errors: [], session_errors: {}, invalid_records: [])
|
|
150
250
|
end
|
|
151
251
|
|
|
152
252
|
it 'fails closed for null map entries, invalid JSON, unreadable stores and unsafe embeddings' do
|
|
@@ -154,8 +254,8 @@ describe PWN::Sessions do
|
|
|
154
254
|
learning = dependency_fixture('learning.jsonl', {})
|
|
155
255
|
File.write(learning, '{')
|
|
156
256
|
memory = dependency_fixture('memory.json', {})
|
|
157
|
-
allow(File).to receive(:
|
|
158
|
-
allow(File).to receive(:
|
|
257
|
+
allow(File).to receive(:binread).and_call_original
|
|
258
|
+
allow(File).to receive(:binread).with(memory).and_raise(Errno::EACCES)
|
|
159
259
|
database = File.join(Dir.home, '.pwn', 'embeddings', "#{sid}.db")
|
|
160
260
|
FileUtils.mkdir_p(database)
|
|
161
261
|
result = described_class.dependency_index
|
|
@@ -165,13 +265,13 @@ describe PWN::Sessions do
|
|
|
165
265
|
it 'distinguishes swarm artifact IDs and unrelated observation tags from session provenance' do
|
|
166
266
|
dependency_fixture('artifacts/manifest.jsonl', { session: sid, kind: 'swarm-bus' })
|
|
167
267
|
dependency_fixture('extrospection.json', { observations: [{ source: 'auto_extrospect', tags: ['drift', 'unrelated', sid] }] })
|
|
168
|
-
expect(described_class.dependency_index).to eq(dependencies: {}, errors: [])
|
|
268
|
+
expect(described_class.dependency_index).to eq(dependencies: {}, errors: [], session_errors: {}, invalid_records: [])
|
|
169
269
|
end
|
|
170
270
|
|
|
171
271
|
it 'does not accept session ID substrings, whitespace or trailing newlines as references' do
|
|
172
272
|
["prefix#{sid}", "#{sid}suffix", " #{sid}", "#{sid}\n", sid.upcase, 'unrelated-session'].each do |value|
|
|
173
273
|
dependency_fixture('learning.jsonl', { session_id: value })
|
|
174
|
-
expect(described_class.dependency_index).to eq(dependencies: {}, errors: [])
|
|
274
|
+
expect(described_class.dependency_index).to eq(dependencies: {}, errors: [], session_errors: {}, invalid_records: [])
|
|
175
275
|
end
|
|
176
276
|
end
|
|
177
277
|
end
|
|
@@ -219,8 +319,8 @@ describe PWN::Sessions do
|
|
|
219
319
|
stored = JSON.generate(title: long, title_source: 'summary', summary: 'Keep this complete summary.', summary_turns: 2)
|
|
220
320
|
File.write(path, stored)
|
|
221
321
|
transcript = File.binread(session[:path])
|
|
222
|
-
expect(described_class.list.first[:title]).to eq('One two three four five six seven')
|
|
223
|
-
expect(described_class.resolve(identifier: described_class.list.first[:title])).to eq(session[:id])
|
|
322
|
+
expect(described_class.list(include_hidden: true).first[:title]).to eq('One two three four five six seven')
|
|
323
|
+
expect(described_class.resolve(identifier: described_class.list(include_hidden: true).first[:title])).to eq(session[:id])
|
|
224
324
|
expect(described_class.metadata(session_id: session[:id])[:summary]).to eq('Keep this complete summary.')
|
|
225
325
|
expect(File.binread(path)).to eq(stored)
|
|
226
326
|
expect(File.binread(session[:path])).to eq(transcript)
|
|
@@ -253,7 +353,7 @@ describe PWN::Sessions do
|
|
|
253
353
|
it 'persists an early grounded title and resolves exact titles without changing ids' do
|
|
254
354
|
session = described_class.create(id: 'title_test')
|
|
255
355
|
described_class.append(session_id: session[:id], role: 'user', content: 'Investigate café "login" failures')
|
|
256
|
-
row = described_class.list.find { |item| item[:id] == session[:id] }
|
|
356
|
+
row = described_class.list(include_hidden: true).find { |item| item[:id] == session[:id] }
|
|
257
357
|
expect(row[:title]).to eq('Investigate café "login" failures')
|
|
258
358
|
expect(described_class.resolve(identifier: row[:title])).to eq('title_test')
|
|
259
359
|
expect(described_class.resolve(identifier: 'title_test')).to eq('title_test')
|
|
@@ -276,11 +376,11 @@ describe PWN::Sessions do
|
|
|
276
376
|
|
|
277
377
|
it 'resumes a listed title after an asynchronous refresh and refuses ambiguous historical names' do
|
|
278
378
|
sid = described_class.create(id: 'listed_before_refresh', title: 'Displayed café title')[:id]
|
|
279
|
-
displayed = described_class.list.first[:title]
|
|
379
|
+
displayed = described_class.list(include_hidden: true).first[:title]
|
|
280
380
|
described_class.append(session_id: sid, content: 'Repair login')
|
|
281
381
|
allow(PWN::AI::Router).to receive(:summarize).and_return(JSON.generate(title: 'Updated login repair', summary: 'Repaired login'))
|
|
282
382
|
described_class.refresh_title(session_id: sid)
|
|
283
|
-
expect(described_class.list.first[:title]).to eq('Updated login repair')
|
|
383
|
+
expect(described_class.list(include_hidden: true).first[:title]).to eq('Updated login repair')
|
|
284
384
|
expect(described_class.resolve(identifier: displayed)).to eq(sid)
|
|
285
385
|
described_class.create(id: 'duplicate_old_title', title: displayed)
|
|
286
386
|
expect { described_class.resolve(identifier: displayed) }.to raise_error(ArgumentError, /Ambiguous.*listed_before_refresh.*duplicate_old_title|Ambiguous.*duplicate_old_title.*listed_before_refresh/)
|
|
@@ -298,7 +398,7 @@ describe PWN::Sessions do
|
|
|
298
398
|
expect(described_class.metadata(session_id: session[:id])).to include(id: 'legacy', title: 'Legacy title')
|
|
299
399
|
File.write(session[:path], JSON.generate(role: 'user', content: 'old turn'))
|
|
300
400
|
File.delete(path)
|
|
301
|
-
expect(described_class.list.first[:title]).to eq('pwn-ai session legacy')
|
|
401
|
+
expect(described_class.list(include_hidden: true).first[:title]).to eq('pwn-ai session legacy')
|
|
302
402
|
end
|
|
303
403
|
|
|
304
404
|
it 'preserves the previous title and retries after invalid or unavailable summaries' do
|
data/third_party/pwn_rdoc.jsonl
CHANGED
|
@@ -2268,6 +2268,7 @@
|
|
|
2268
2268
|
{"messages":[{"role":"user","content":"PWN::JSONText.help Usage"},{"role":"assistant","content":"`PWN::JSONText.help`: "}]}
|
|
2269
2269
|
{"messages":[{"role":"user","content":"PWN::JSONText.prepare Usage"},{"role":"assistant","content":"`PWN::JSONText.prepare`: Supported Method Parameters\n\nsafe = PWN::JSONText.prepare(\n\nvalue: 'required - string, hash, or array that may contain binary-tagged text',\ndepth: 'optional - nesting already walked; containers stop at 100'\n\n)\n"}]}
|
|
2270
2270
|
{"messages":[{"role":"user","content":"PWN::Memory.archive_expired! Usage"},{"role":"assistant","content":"`PWN::Memory.archive_expired!`: "}]}
|
|
2271
|
+
{"messages":[{"role":"user","content":"PWN::Memory.atomic_write Usage"},{"role":"assistant","content":"`PWN::Memory.atomic_write`: "}]}
|
|
2271
2272
|
{"messages":[{"role":"user","content":"PWN::Memory.authors Usage"},{"role":"assistant","content":"`PWN::Memory.authors`: Author(s)\n\n0day Inc. <support@0dayinc.com>\n"}]}
|
|
2272
2273
|
{"messages":[{"role":"user","content":"PWN::Memory.clear Usage"},{"role":"assistant","content":"`PWN::Memory.clear`: Supported Method Parameters\n\nPWN::Memory.clear(force: true)\n"}]}
|
|
2273
2274
|
{"messages":[{"role":"user","content":"PWN::Memory.current_session_id Usage"},{"role":"assistant","content":"`PWN::Memory.current_session_id`: "}]}
|
|
@@ -2290,6 +2291,8 @@
|
|
|
2290
2291
|
{"messages":[{"role":"user","content":"PWN::Memory.save Usage"},{"role":"assistant","content":"`PWN::Memory.save`: Supported Method Parameters\n\nPWN::Memory.save(mem: memory_hash)\n"}]}
|
|
2291
2292
|
{"messages":[{"role":"user","content":"PWN::Memory.session_turns Usage"},{"role":"assistant","content":"`PWN::Memory.session_turns`: "}]}
|
|
2292
2293
|
{"messages":[{"role":"user","content":"PWN::Memory.to_context Usage"},{"role":"assistant","content":"`PWN::Memory.to_context`: Supported Method Parameters\n\ncontext = PWN::Memory.to_context(limit: 20) (used internally by pwn-ai hook to inject into system prompt)\n"}]}
|
|
2294
|
+
{"messages":[{"role":"user","content":"PWN::Memory.transaction Usage"},{"role":"assistant","content":"`PWN::Memory.transaction`: "}]}
|
|
2295
|
+
{"messages":[{"role":"user","content":"PWN::Memory.transaction_owned? Usage"},{"role":"assistant","content":"`PWN::Memory.transaction_owned?`: "}]}
|
|
2293
2296
|
{"messages":[{"role":"user","content":"PWN::Memory.turn_pairs Usage"},{"role":"assistant","content":"`PWN::Memory.turn_pairs`: "}]}
|
|
2294
2297
|
{"messages":[{"role":"user","content":"PWN::MemoryIndex.authors Usage"},{"role":"assistant","content":"`PWN::MemoryIndex.authors`: Author(s)\n\n0day Inc. <support@0dayinc.com>\n"}]}
|
|
2295
2298
|
{"messages":[{"role":"user","content":"PWN::MemoryIndex.available? Usage"},{"role":"assistant","content":"`PWN::MemoryIndex.available?`: Supported Method Parameters\n\nbool = PWN::MemoryIndex.available?\n"}]}
|
|
@@ -4632,14 +4635,18 @@
|
|
|
4632
4635
|
{"messages":[{"role":"user","content":"PWN::Sessions.append Usage"},{"role":"assistant","content":"`PWN::Sessions.append`: Supported Method Parameters\n\nPWN::Sessions.append(\n\nsession_id: 'required',\nrole: 'user|assistant|system|observation',\ncontent: 'the message or obs'\n\n)\n"}]}
|
|
4633
4636
|
{"messages":[{"role":"user","content":"PWN::Sessions.authors Usage"},{"role":"assistant","content":"`PWN::Sessions.authors`: "}]}
|
|
4634
4637
|
{"messages":[{"role":"user","content":"PWN::Sessions.bounded_title Usage"},{"role":"assistant","content":"`PWN::Sessions.bounded_title`: "}]}
|
|
4638
|
+
{"messages":[{"role":"user","content":"PWN::Sessions.catalog Usage"},{"role":"assistant","content":"`PWN::Sessions.catalog`: "}]}
|
|
4635
4639
|
{"messages":[{"role":"user","content":"PWN::Sessions.cleanup_transcript_valid? Usage"},{"role":"assistant","content":"`PWN::Sessions.cleanup_transcript_valid?`: "}]}
|
|
4636
4640
|
{"messages":[{"role":"user","content":"PWN::Sessions.compact_transcript! Usage"},{"role":"assistant","content":"`PWN::Sessions.compact_transcript!`: "}]}
|
|
4641
|
+
{"messages":[{"role":"user","content":"PWN::Sessions.complete_policy_trajectory? Usage"},{"role":"assistant","content":"`PWN::Sessions.complete_policy_trajectory?`: "}]}
|
|
4637
4642
|
{"messages":[{"role":"user","content":"PWN::Sessions.create Usage"},{"role":"assistant","content":"`PWN::Sessions.create`: Supported Method Parameters\n\nsession = PWN::Sessions.create(\n\ntitle: 'optional - human title, capped at seven whitespace-separated words',\nsource: 'optional - e.g. pwn-ai',\nid: 'optional - fixed session id (tests / replay); default timestamp_hex',\nactive: 'optional - return an owned lease with the new session'\n\n)\n"}]}
|
|
4638
4643
|
{"messages":[{"role":"user","content":"PWN::Sessions.deactivate Usage"},{"role":"assistant","content":"`PWN::Sessions.deactivate`: Supported Method Parameters\n\nPWN::Sessions.deactivate(lease: ‘required - handle returned by activate’)\n"}]}
|
|
4639
4644
|
{"messages":[{"role":"user","content":"PWN::Sessions.delete Usage"},{"role":"assistant","content":"`PWN::Sessions.delete`: Supported Method Parameters\n\nPWN::Sessions.delete(\n\nsession_id: 'required',\nforce: 'optional - Boolean bypass pin policy (default false)'\n\n)\n"}]}
|
|
4645
|
+
{"messages":[{"role":"user","content":"PWN::Sessions.dependency_error_owners Usage"},{"role":"assistant","content":"`PWN::Sessions.dependency_error_owners`: "}]}
|
|
4640
4646
|
{"messages":[{"role":"user","content":"PWN::Sessions.dependency_ids Usage"},{"role":"assistant","content":"`PWN::Sessions.dependency_ids`: "}]}
|
|
4641
4647
|
{"messages":[{"role":"user","content":"PWN::Sessions.dependency_index Usage"},{"role":"assistant","content":"`PWN::Sessions.dependency_index`: Supported Method Parameters\n\nreferences = PWN::Sessions.dependency_index\n"}]}
|
|
4642
4648
|
{"messages":[{"role":"user","content":"PWN::Sessions.dependency_select Usage"},{"role":"assistant","content":"`PWN::Sessions.dependency_select`: "}]}
|
|
4649
|
+
{"messages":[{"role":"user","content":"PWN::Sessions.dependency_units Usage"},{"role":"assistant","content":"`PWN::Sessions.dependency_units`: "}]}
|
|
4643
4650
|
{"messages":[{"role":"user","content":"PWN::Sessions.dependency_value Usage"},{"role":"assistant","content":"`PWN::Sessions.dependency_value`: "}]}
|
|
4644
4651
|
{"messages":[{"role":"user","content":"PWN::Sessions.event_dependency_ids Usage"},{"role":"assistant","content":"`PWN::Sessions.event_dependency_ids`: "}]}
|
|
4645
4652
|
{"messages":[{"role":"user","content":"PWN::Sessions.expand_tokens Usage"},{"role":"assistant","content":"`PWN::Sessions.expand_tokens`: "}]}
|
|
@@ -4650,6 +4657,8 @@
|
|
|
4650
4657
|
{"messages":[{"role":"user","content":"PWN::Sessions.load Usage"},{"role":"assistant","content":"`PWN::Sessions.load`: Supported Method Parameters\n\ntranscript = PWN::Sessions.load(session_id: ‘required’)\n"}]}
|
|
4651
4658
|
{"messages":[{"role":"user","content":"PWN::Sessions.memory_dependency_ids Usage"},{"role":"assistant","content":"`PWN::Sessions.memory_dependency_ids`: "}]}
|
|
4652
4659
|
{"messages":[{"role":"user","content":"PWN::Sessions.metadata Usage"},{"role":"assistant","content":"`PWN::Sessions.metadata`: "}]}
|
|
4660
|
+
{"messages":[{"role":"user","content":"PWN::Sessions.mistake_dependency_ids Usage"},{"role":"assistant","content":"`PWN::Sessions.mistake_dependency_ids`: "}]}
|
|
4661
|
+
{"messages":[{"role":"user","content":"PWN::Sessions.practice_dependency_ids Usage"},{"role":"assistant","content":"`PWN::Sessions.practice_dependency_ids`: "}]}
|
|
4653
4662
|
{"messages":[{"role":"user","content":"PWN::Sessions.previous_id Usage"},{"role":"assistant","content":"`PWN::Sessions.previous_id`: Supported Method Parameters\n\nid = PWN::Sessions.previous_id(\n\nexclude_session_id: 'optional - current session to skip'\n\n)\n"}]}
|
|
4654
4663
|
{"messages":[{"role":"user","content":"PWN::Sessions.protected_session_ids Usage"},{"role":"assistant","content":"`PWN::Sessions.protected_session_ids`: "}]}
|
|
4655
4664
|
{"messages":[{"role":"user","content":"PWN::Sessions.provisional_title Usage"},{"role":"assistant","content":"`PWN::Sessions.provisional_title`: "}]}
|
|
@@ -4658,12 +4667,15 @@
|
|
|
4658
4667
|
{"messages":[{"role":"user","content":"PWN::Sessions.redact Usage"},{"role":"assistant","content":"`PWN::Sessions.redact`: "}]}
|
|
4659
4668
|
{"messages":[{"role":"user","content":"PWN::Sessions.refresh_title Usage"},{"role":"assistant","content":"`PWN::Sessions.refresh_title`: "}]}
|
|
4660
4669
|
{"messages":[{"role":"user","content":"PWN::Sessions.register_activity_owner Usage"},{"role":"assistant","content":"`PWN::Sessions.register_activity_owner`: "}]}
|
|
4670
|
+
{"messages":[{"role":"user","content":"PWN::Sessions.request_checkpoint_dependencies Usage"},{"role":"assistant","content":"`PWN::Sessions.request_checkpoint_dependencies`: "}]}
|
|
4661
4671
|
{"messages":[{"role":"user","content":"PWN::Sessions.resolve Usage"},{"role":"assistant","content":"`PWN::Sessions.resolve`: "}]}
|
|
4662
4672
|
{"messages":[{"role":"user","content":"PWN::Sessions.retain Usage"},{"role":"assistant","content":"`PWN::Sessions.retain`: "}]}
|
|
4673
|
+
{"messages":[{"role":"user","content":"PWN::Sessions.retention_status Usage"},{"role":"assistant","content":"`PWN::Sessions.retention_status`: Supported Method Parameters\n\nstatus = PWN::Sessions.retention_status(session_id: id, references: index)\n"}]}
|
|
4663
4674
|
{"messages":[{"role":"user","content":"PWN::Sessions.sessions_dir Usage"},{"role":"assistant","content":"`PWN::Sessions.sessions_dir`: Supported Method Parameters\n\ndir = PWN::Sessions.sessions_dir\n"}]}
|
|
4664
4675
|
{"messages":[{"role":"user","content":"PWN::Sessions.stats Usage"},{"role":"assistant","content":"`PWN::Sessions.stats`: Supported Method Parameters\n\nstats = PWN::Sessions.stats\n"}]}
|
|
4665
4676
|
{"messages":[{"role":"user","content":"PWN::Sessions.stub_session? Usage"},{"role":"assistant","content":"`PWN::Sessions.stub_session?`: "}]}
|
|
4666
4677
|
{"messages":[{"role":"user","content":"PWN::Sessions.summary_title_valid? Usage"},{"role":"assistant","content":"`PWN::Sessions.summary_title_valid?`: "}]}
|
|
4678
|
+
{"messages":[{"role":"user","content":"PWN::Sessions.support_path Usage"},{"role":"assistant","content":"`PWN::Sessions.support_path`: Supported Method Parameters\n\npath = PWN::Sessions.support_path(kind: :metadata, session_id: id)\n"}]}
|
|
4667
4679
|
{"messages":[{"role":"user","content":"PWN::Sessions.title_status Usage"},{"role":"assistant","content":"`PWN::Sessions.title_status`: Supported Method Parameters\n\nstatus = PWN::Sessions.title_status(session_id: ‘required - canonical session ID’)\n"}]}
|
|
4668
4680
|
{"messages":[{"role":"user","content":"PWN::Sessions.to_llm_messages Usage"},{"role":"assistant","content":"`PWN::Sessions.to_llm_messages`: "}]}
|
|
4669
4681
|
{"messages":[{"role":"user","content":"PWN::Sessions.to_response_history Usage"},{"role":"assistant","content":"`PWN::Sessions.to_response_history`: Supported Method Parameters\n\nhistory_for_ai = PWN::Sessions.to_response_history(session_id:) (converts transcript to the response_history format used by PWN::AI::* .chat)\n"}]}
|