protege 0.1.0.alpha.2 → 0.1.0.alpha.7
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/MIT-LICENSE +21 -0
- data/Rakefile +1 -3
- data/app/assets/builds/protege.css +76 -83
- data/app/controllers/concerns/protege/agent_scoped.rb +22 -0
- data/app/controllers/concerns/protege/agent_toolkit_scoped.rb +22 -0
- data/app/controllers/protege/access_rules_controller.rb +13 -13
- data/app/controllers/protege/agent_toolkit_rules_controller.rb +62 -0
- data/app/controllers/protege/agent_toolkits_controller.rb +44 -0
- data/app/controllers/protege/agents/agent_toolkits_controller.rb +65 -0
- data/app/controllers/protege/agents_controller.rb +118 -0
- data/app/controllers/protege/archives_controller.rb +18 -18
- data/app/controllers/protege/home_controller.rb +1 -1
- data/app/controllers/protege/messages_controller.rb +1 -1
- data/app/controllers/protege/replies_controller.rb +3 -3
- data/app/controllers/protege/responsibilities_controller.rb +7 -7
- data/app/controllers/protege/threads_controller.rb +4 -4
- data/app/controllers/protege/toolkits_controller.rb +84 -0
- data/app/helpers/protege/agents_helper.rb +75 -0
- data/app/helpers/protege/application_helper.rb +3 -2
- data/app/helpers/protege/components/badges_helper.rb +11 -2
- data/app/helpers/protege/components/forms_helper.rb +47 -12
- data/app/helpers/protege/components/typography_helper.rb +1 -1
- data/app/helpers/protege/messages_helper.rb +2 -2
- data/app/helpers/protege/responsibilities_helper.rb +2 -2
- data/app/helpers/protege/threads_helper.rb +11 -11
- data/app/helpers/protege/toolkits_helper.rb +66 -0
- data/app/hooks/protege/event_logger_hook.rb +8 -8
- data/app/jobs/protege/console_inference_job.rb +8 -8
- data/app/jobs/protege/inference_job.rb +11 -11
- data/app/jobs/protege/responsibility_job.rb +10 -10
- data/app/mailboxes/protege/agent_mailbox.rb +54 -29
- data/app/mailers/protege/alert_mailer.rb +41 -0
- data/app/mailers/protege/application_mailer.rb +9 -8
- data/app/models/concerns/protege/broadcastable_agent.rb +50 -0
- data/app/models/concerns/protege/broadcastable_toolkit.rb +49 -0
- data/app/models/concerns/protege/toolable.rb +108 -0
- data/app/models/protege/access_rule.rb +12 -12
- data/app/models/protege/{persona.rb → agent.rb} +45 -45
- data/app/models/protege/agent_toolkit.rb +50 -0
- data/app/models/protege/agent_toolkit_rule.rb +25 -0
- data/app/models/protege/application_record.rb +1 -1
- data/app/models/protege/email_thread.rb +16 -13
- data/app/models/protege/message.rb +36 -20
- data/app/models/protege/responsibility.rb +12 -12
- data/app/models/protege/tool_use.rb +6 -6
- data/app/models/protege/toolkit.rb +115 -0
- data/app/models/protege/trace.rb +1 -1
- data/app/providers/protege/open_router_provider.rb +17 -0
- data/app/resolvers/README.md +4 -4
- data/app/resolvers/protege/load_file_resolver.rb +5 -5
- data/app/resolvers/protege/load_text_resolver.rb +3 -3
- data/app/resolvers/protege/thread_history_resolver.rb +1 -1
- data/app/services/protege/message_search.rb +2 -2
- data/app/services/protege/system_toolkits.rb +67 -0
- data/app/tools/protege/create_file_tool.rb +2 -0
- data/app/tools/protege/read_attachment_tool.rb +3 -1
- data/app/tools/protege/search_emails_tool.rb +15 -13
- data/app/tools/protege/send_email_tool.rb +60 -18
- data/app/tools/protege/web_fetch_tool.rb +2 -0
- data/app/tools/protege/web_search_tool.rb +3 -1
- data/app/views/layouts/mailer.text.erb +1 -0
- data/app/views/protege/access_rules/create.turbo_stream.slim +3 -3
- data/app/views/protege/agent_toolkit_rules/create.turbo_stream.slim +6 -0
- data/app/views/protege/agent_toolkits/_gate_rule.html.slim +7 -0
- data/app/views/protege/agent_toolkits/_gate_rule_form.html.slim +8 -0
- data/app/views/protege/agent_toolkits/_gate_rules.html.slim +19 -0
- data/app/views/protege/agent_toolkits/show.html.slim +17 -0
- data/app/views/protege/{personas → agents}/_access_rule.html.slim +1 -1
- data/app/views/protege/{personas → agents}/_access_rule_form.html.slim +1 -1
- data/app/views/protege/{personas → agents}/_access_rules.html.slim +5 -5
- data/app/views/protege/agents/_actions.html.slim +15 -0
- data/app/views/protege/agents/_agent_sidebar_item.html.slim +5 -0
- data/app/views/protege/agents/_agent_toolkit.html.slim +7 -0
- data/app/views/protege/agents/_agent_toolkit_form.html.slim +7 -0
- data/app/views/protege/agents/_form.html.slim +25 -0
- data/app/views/protege/agents/_sidebar.html.slim +11 -0
- data/app/views/protege/agents/_toolkits.html.slim +19 -0
- data/app/views/protege/agents/agent_toolkits/create.turbo_stream.slim +6 -0
- data/app/views/protege/agents/edit.html.slim +7 -0
- data/app/views/protege/agents/index.html.slim +6 -0
- data/app/views/protege/agents/new.html.slim +7 -0
- data/app/views/protege/agents/show.html.slim +29 -0
- data/app/views/protege/alert_mailer/inference_failed.text.erb +4 -0
- data/app/views/protege/email_domains/show.html.slim +1 -1
- data/app/views/protege/home/show.html.slim +13 -13
- data/app/views/protege/responsibilities/_form.html.slim +2 -2
- data/app/views/protege/responsibilities/_responsibility_sidebar_item.html.slim +1 -1
- data/app/views/protege/responsibilities/new.html.slim +1 -1
- data/app/views/protege/responsibilities/show.html.slim +2 -2
- data/app/views/protege/responsibility_runs/show.html.slim +1 -1
- data/app/views/protege/shared/_header.html.slim +2 -1
- data/app/views/protege/shared/_hotkeys.html.slim +15 -11
- data/app/views/protege/threads/new.html.slim +2 -2
- data/app/views/protege/toolkits/_form.html.slim +13 -0
- data/app/views/protege/toolkits/_sidebar.html.slim +11 -0
- data/app/views/protege/toolkits/_toolkit_sidebar_item.html.slim +5 -0
- data/app/views/protege/toolkits/edit.html.slim +7 -0
- data/app/views/protege/toolkits/index.html.slim +6 -0
- data/app/views/protege/toolkits/new.html.slim +7 -0
- data/app/views/protege/toolkits/show.html.slim +13 -0
- data/config/routes.rb +12 -1
- data/db/migrate/20260707120000_replace_persona_active_with_archived_at.rb +1 -1
- data/db/migrate/20260708120000_add_disabled_tool_ids_to_personas.rb +1 -1
- data/db/migrate/20260728140000_scope_message_and_thread_uniqueness_per_persona.rb +16 -0
- data/db/migrate/20260812000001_create_protege_toolkits.rb +37 -0
- data/db/migrate/20260815000001_remove_disabled_tool_ids_from_personas.rb +21 -0
- data/db/migrate/20260815000002_add_key_to_protege_toolkits.rb +22 -0
- data/db/migrate/20260815100000_rename_personas_to_agents.rb +24 -0
- data/lib/generators/protege/agent/agent_generator.rb +35 -0
- data/lib/generators/protege/{persona/templates/persona.rb.tt → agent/templates/agent.rb.tt} +9 -9
- data/lib/generators/protege/extension_naming.rb +1 -1
- data/lib/generators/protege/hook/templates/hook.rb.tt +2 -2
- data/lib/generators/protege/install/install_generator.rb +16 -11
- data/lib/generators/protege/install/templates/initializer.rb.tt +17 -6
- data/lib/generators/protege/postfix/templates/deploy/mail/MAIL.md +2 -2
- data/lib/generators/protege/resolver/resolver_generator.rb +2 -2
- data/lib/generators/protege/resolver/templates/resolver.rb.tt +4 -4
- data/lib/generators/protege/tool/templates/tool.rb.tt +7 -5
- data/lib/protege/configuration.rb +43 -8
- data/lib/protege/engine.rb +3 -1
- data/lib/protege/errors/tool_not_available_error.rb +7 -6
- data/lib/protege/events/event.rb +2 -2
- data/lib/protege/events/inference_chunk_event.rb +1 -1
- data/lib/protege/events/inference_completed_event.rb +1 -1
- data/lib/protege/events/inference_failed_event.rb +1 -1
- data/lib/protege/events/inference_generated_event.rb +1 -1
- data/lib/protege/events/inference_max_turns_reached_event.rb +1 -1
- data/lib/protege/events/inference_started_event.rb +1 -1
- data/lib/protege/events/loop_run_completed_event.rb +1 -1
- data/lib/protege/events/loop_run_enqueued_event.rb +1 -1
- data/lib/protege/events/loop_run_failed_event.rb +1 -1
- data/lib/protege/events/loop_run_started_event.rb +1 -1
- data/lib/protege/events/tool_call_completed_event.rb +1 -1
- data/lib/protege/events/tool_call_failed_event.rb +1 -1
- data/lib/protege/events/tool_call_started_event.rb +1 -1
- data/lib/protege/events/tool_calls_received_event.rb +1 -1
- data/lib/protege/extensions/hook.rb +1 -0
- data/lib/protege/extensions/hook_mixin.rb +1 -1
- data/lib/protege/extensions/manifest.rb +67 -0
- data/lib/protege/extensions/manifested.rb +81 -0
- data/lib/protege/extensions/provider.rb +1 -0
- data/lib/protege/extensions/provider_mixin.rb +9 -17
- data/lib/protege/extensions/resolver.rb +2 -1
- data/lib/protege/extensions/resolver_mixin.rb +2 -2
- data/lib/protege/extensions/tool.rb +1 -0
- data/lib/protege/extensions/tool_mixin.rb +16 -40
- data/lib/protege/gateway/access_control.rb +19 -19
- data/lib/protege/gateway/access_policy.rb +2 -2
- data/lib/protege/gateway/mail/outbound.rb +22 -5
- data/lib/protege/gateway.rb +48 -37
- data/lib/protege/loop/scheduler.rb +1 -1
- data/lib/protege/orchestrator/context.rb +8 -8
- data/lib/protege/orchestrator/harness.rb +26 -24
- data/lib/protege/orchestrator/reply_context.rb +3 -3
- data/lib/protege/orchestrator/reply_harness.rb +8 -8
- data/lib/protege/orchestrator/resolver_chain.rb +3 -3
- data/lib/protege/orchestrator/responsibility_context.rb +4 -4
- data/lib/protege/orchestrator/responsibility_harness.rb +8 -8
- data/lib/protege/orchestrator.rb +7 -7
- data/lib/protege/subscribers/alerter.rb +117 -0
- data/lib/protege/subscribers/tracing.rb +1 -1
- data/lib/protege/version.rb +1 -1
- data/lib/protege.rb +2 -2
- data/lib/tasks/protege_tasks.rake +12 -0
- metadata +66 -23
- data/app/controllers/concerns/protege/persona_scoped.rb +0 -22
- data/app/controllers/protege/personas_controller.rb +0 -118
- data/app/helpers/protege/personas_helper.rb +0 -90
- data/app/models/concerns/protege/broadcastable_persona.rb +0 -50
- data/app/models/concerns/protege/tool_scoped.rb +0 -88
- data/app/views/protege/personas/_actions.html.slim +0 -15
- data/app/views/protege/personas/_form.html.slim +0 -29
- data/app/views/protege/personas/_persona_sidebar_item.html.slim +0 -5
- data/app/views/protege/personas/_sidebar.html.slim +0 -11
- data/app/views/protege/personas/edit.html.slim +0 -7
- data/app/views/protege/personas/index.html.slim +0 -6
- data/app/views/protege/personas/new.html.slim +0 -7
- data/app/views/protege/personas/show.html.slim +0 -37
- data/lib/generators/protege/persona/persona_generator.rb +0 -35
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d413f57504bbdb848d33fd0afd7fdc616a409de2b5d3107c38a2d169bd1e1c6f
|
|
4
|
+
data.tar.gz: a80f880c36d5b1add111ca5176abfb27416fcb18ae63d2bf4504fd97d61e0912
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0f9ebf231169742d602abad8f806793599636a6e15ec196d19672128e9ac123fb9db72ba4738e33cc86fd1bcf546dfb9f69ae0aebc9f935400a4a24347b584a0
|
|
7
|
+
data.tar.gz: 211573228c71e00cd37ea479419fe13cf7260bcc303443ed3720a7c991f9c2634e6fb1628958c3cb23f9e77121055e2d81a479a44d33eebf3ff7444964a6ff65
|
data/MIT-LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Sebastian Scholl
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
data/Rakefile
CHANGED
|
@@ -8,9 +8,7 @@ require 'rake/testtask'
|
|
|
8
8
|
# `git push origin HEAD`) is both redundant and fails on the detached HEAD. Skip it there so
|
|
9
9
|
# `rake release` only builds and publishes the gem (via trusted publishing); local `rake release`
|
|
10
10
|
# keeps its full behavior.
|
|
11
|
-
if ENV['CI'] && Rake::Task.task_defined?('release:source_control_push')
|
|
12
|
-
Rake::Task['release:source_control_push'].clear
|
|
13
|
-
end
|
|
11
|
+
Rake::Task['release:source_control_push'].clear if ENV['CI'] && Rake::Task.task_defined?('release:source_control_push')
|
|
14
12
|
|
|
15
13
|
Rake::TestTask.new(:test) do |t|
|
|
16
14
|
t.libs << 'test'
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! tailwindcss v4.3.
|
|
1
|
+
/*! tailwindcss v4.3.0 | MIT License | https://tailwindcss.com */
|
|
2
2
|
@layer properties;
|
|
3
3
|
@layer theme, base, components, utilities;
|
|
4
4
|
@layer theme {
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
--font-weight-bold: 700;
|
|
39
39
|
--tracking-wide: 0.025em;
|
|
40
40
|
--tracking-wider: 0.05em;
|
|
41
|
+
--leading-snug: 1.375;
|
|
41
42
|
--leading-relaxed: 1.625;
|
|
42
43
|
--radius-sm: 0.25rem;
|
|
43
44
|
--radius-md: 0.375rem;
|
|
@@ -218,10 +219,10 @@
|
|
|
218
219
|
position: static;
|
|
219
220
|
}
|
|
220
221
|
.inset-0 {
|
|
221
|
-
inset: 0;
|
|
222
|
+
inset: calc(var(--spacing) * 0);
|
|
222
223
|
}
|
|
223
224
|
.right-0 {
|
|
224
|
-
right: 0;
|
|
225
|
+
right: calc(var(--spacing) * 0);
|
|
225
226
|
}
|
|
226
227
|
.z-10 {
|
|
227
228
|
z-index: 10;
|
|
@@ -260,7 +261,7 @@
|
|
|
260
261
|
margin-top: calc(var(--spacing) * 0.5);
|
|
261
262
|
}
|
|
262
263
|
.mt-1 {
|
|
263
|
-
margin-top: var(--spacing);
|
|
264
|
+
margin-top: calc(var(--spacing) * 1);
|
|
264
265
|
}
|
|
265
266
|
.mt-2 {
|
|
266
267
|
margin-top: calc(var(--spacing) * 2);
|
|
@@ -275,7 +276,7 @@
|
|
|
275
276
|
margin-top: calc(var(--spacing) * 10);
|
|
276
277
|
}
|
|
277
278
|
.mb-1 {
|
|
278
|
-
margin-bottom: var(--spacing);
|
|
279
|
+
margin-bottom: calc(var(--spacing) * 1);
|
|
279
280
|
}
|
|
280
281
|
.mb-3 {
|
|
281
282
|
margin-bottom: calc(var(--spacing) * 3);
|
|
@@ -344,7 +345,7 @@
|
|
|
344
345
|
height: 100%;
|
|
345
346
|
}
|
|
346
347
|
.min-h-0 {
|
|
347
|
-
min-height: 0;
|
|
348
|
+
min-height: calc(var(--spacing) * 0);
|
|
348
349
|
}
|
|
349
350
|
.min-h-\[6rem\] {
|
|
350
351
|
min-height: 6rem;
|
|
@@ -358,6 +359,9 @@
|
|
|
358
359
|
.w-4 {
|
|
359
360
|
width: calc(var(--spacing) * 4);
|
|
360
361
|
}
|
|
362
|
+
.w-5 {
|
|
363
|
+
width: calc(var(--spacing) * 5);
|
|
364
|
+
}
|
|
361
365
|
.w-9 {
|
|
362
366
|
width: calc(var(--spacing) * 9);
|
|
363
367
|
}
|
|
@@ -389,7 +393,7 @@
|
|
|
389
393
|
max-width: var(--container-sm);
|
|
390
394
|
}
|
|
391
395
|
.min-w-0 {
|
|
392
|
-
min-width: 0;
|
|
396
|
+
min-width: calc(var(--spacing) * 0);
|
|
393
397
|
}
|
|
394
398
|
.flex-1 {
|
|
395
399
|
flex: 1;
|
|
@@ -401,7 +405,7 @@
|
|
|
401
405
|
flex-shrink: 0;
|
|
402
406
|
}
|
|
403
407
|
.translate-x-1 {
|
|
404
|
-
--tw-translate-x: var(--spacing);
|
|
408
|
+
--tw-translate-x: calc(var(--spacing) * 1);
|
|
405
409
|
translate: var(--tw-translate-x) var(--tw-translate-y);
|
|
406
410
|
}
|
|
407
411
|
.translate-x-4 {
|
|
@@ -462,8 +466,14 @@
|
|
|
462
466
|
.justify-center {
|
|
463
467
|
justify-content: center;
|
|
464
468
|
}
|
|
469
|
+
.justify-end {
|
|
470
|
+
justify-content: flex-end;
|
|
471
|
+
}
|
|
472
|
+
.gap-0\.5 {
|
|
473
|
+
gap: calc(var(--spacing) * 0.5);
|
|
474
|
+
}
|
|
465
475
|
.gap-1 {
|
|
466
|
-
gap: var(--spacing);
|
|
476
|
+
gap: calc(var(--spacing) * 1);
|
|
467
477
|
}
|
|
468
478
|
.gap-1\.5 {
|
|
469
479
|
gap: calc(var(--spacing) * 1.5);
|
|
@@ -493,8 +503,8 @@
|
|
|
493
503
|
.space-y-1 {
|
|
494
504
|
:where(& > :not(:last-child)) {
|
|
495
505
|
--tw-space-y-reverse: 0;
|
|
496
|
-
margin-block-start: calc(var(--spacing) * var(--tw-space-y-reverse));
|
|
497
|
-
margin-block-end: calc(var(--spacing) * calc(1 - var(--tw-space-y-reverse)));
|
|
506
|
+
margin-block-start: calc(calc(var(--spacing) * 1) * var(--tw-space-y-reverse));
|
|
507
|
+
margin-block-end: calc(calc(var(--spacing) * 1) * calc(1 - var(--tw-space-y-reverse)));
|
|
498
508
|
}
|
|
499
509
|
}
|
|
500
510
|
.space-y-2 {
|
|
@@ -590,7 +600,10 @@
|
|
|
590
600
|
background-color: var(--color-yellow-600);
|
|
591
601
|
}
|
|
592
602
|
.p-0 {
|
|
593
|
-
padding: 0;
|
|
603
|
+
padding: calc(var(--spacing) * 0);
|
|
604
|
+
}
|
|
605
|
+
.p-1\.5 {
|
|
606
|
+
padding: calc(var(--spacing) * 1.5);
|
|
594
607
|
}
|
|
595
608
|
.p-5 {
|
|
596
609
|
padding: calc(var(--spacing) * 5);
|
|
@@ -599,7 +612,7 @@
|
|
|
599
612
|
padding: calc(var(--spacing) * 6);
|
|
600
613
|
}
|
|
601
614
|
.px-1 {
|
|
602
|
-
padding-inline: var(--spacing);
|
|
615
|
+
padding-inline: calc(var(--spacing) * 1);
|
|
603
616
|
}
|
|
604
617
|
.px-1\.5 {
|
|
605
618
|
padding-inline: calc(var(--spacing) * 1.5);
|
|
@@ -620,7 +633,7 @@
|
|
|
620
633
|
padding-block: calc(var(--spacing) * 0.5);
|
|
621
634
|
}
|
|
622
635
|
.py-1 {
|
|
623
|
-
padding-block: var(--spacing);
|
|
636
|
+
padding-block: calc(var(--spacing) * 1);
|
|
624
637
|
}
|
|
625
638
|
.py-1\.5 {
|
|
626
639
|
padding-block: calc(var(--spacing) * 1.5);
|
|
@@ -637,12 +650,24 @@
|
|
|
637
650
|
.py-8 {
|
|
638
651
|
padding-block: calc(var(--spacing) * 8);
|
|
639
652
|
}
|
|
653
|
+
.py-px {
|
|
654
|
+
padding-block: 1px;
|
|
655
|
+
}
|
|
656
|
+
.pt-1 {
|
|
657
|
+
padding-top: calc(var(--spacing) * 1);
|
|
658
|
+
}
|
|
640
659
|
.pt-2 {
|
|
641
660
|
padding-top: calc(var(--spacing) * 2);
|
|
642
661
|
}
|
|
662
|
+
.pt-3 {
|
|
663
|
+
padding-top: calc(var(--spacing) * 3);
|
|
664
|
+
}
|
|
643
665
|
.pr-4 {
|
|
644
666
|
padding-right: calc(var(--spacing) * 4);
|
|
645
667
|
}
|
|
668
|
+
.pr-6 {
|
|
669
|
+
padding-right: calc(var(--spacing) * 6);
|
|
670
|
+
}
|
|
646
671
|
.pb-2 {
|
|
647
672
|
padding-bottom: calc(var(--spacing) * 2);
|
|
648
673
|
}
|
|
@@ -683,10 +708,21 @@
|
|
|
683
708
|
font-size: var(--text-xs);
|
|
684
709
|
line-height: var(--tw-leading, var(--text-xs--line-height));
|
|
685
710
|
}
|
|
711
|
+
.text-\[10px\] {
|
|
712
|
+
font-size: 10px;
|
|
713
|
+
}
|
|
714
|
+
.leading-none {
|
|
715
|
+
--tw-leading: 1;
|
|
716
|
+
line-height: 1;
|
|
717
|
+
}
|
|
686
718
|
.leading-relaxed {
|
|
687
719
|
--tw-leading: var(--leading-relaxed);
|
|
688
720
|
line-height: var(--leading-relaxed);
|
|
689
721
|
}
|
|
722
|
+
.leading-snug {
|
|
723
|
+
--tw-leading: var(--leading-snug);
|
|
724
|
+
line-height: var(--leading-snug);
|
|
725
|
+
}
|
|
690
726
|
.font-bold {
|
|
691
727
|
--tw-font-weight: var(--font-weight-bold);
|
|
692
728
|
font-weight: var(--font-weight-bold);
|
|
@@ -710,6 +746,9 @@
|
|
|
710
746
|
.break-all {
|
|
711
747
|
word-break: break-all;
|
|
712
748
|
}
|
|
749
|
+
.whitespace-nowrap {
|
|
750
|
+
white-space: nowrap;
|
|
751
|
+
}
|
|
713
752
|
.whitespace-pre-wrap {
|
|
714
753
|
white-space: pre-wrap;
|
|
715
754
|
}
|
|
@@ -747,6 +786,12 @@
|
|
|
747
786
|
-webkit-font-smoothing: antialiased;
|
|
748
787
|
-moz-osx-font-smoothing: grayscale;
|
|
749
788
|
}
|
|
789
|
+
.opacity-60 {
|
|
790
|
+
opacity: 60%;
|
|
791
|
+
}
|
|
792
|
+
.opacity-70 {
|
|
793
|
+
opacity: 70%;
|
|
794
|
+
}
|
|
750
795
|
.shadow-lg {
|
|
751
796
|
--tw-shadow: 0 10px 15px -3px var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 4px 6px -4px var(--tw-shadow-color, rgb(0 0 0 / 0.1));
|
|
752
797
|
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
|
|
@@ -755,14 +800,16 @@
|
|
|
755
800
|
--tw-shadow: 0 1px 3px 0 var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 1px 2px -1px var(--tw-shadow-color, rgb(0 0 0 / 0.1));
|
|
756
801
|
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
|
|
757
802
|
}
|
|
758
|
-
.filter {
|
|
759
|
-
filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,);
|
|
760
|
-
}
|
|
761
803
|
.transition-colors {
|
|
762
804
|
transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to;
|
|
763
805
|
transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
|
|
764
806
|
transition-duration: var(--tw-duration, var(--default-transition-duration));
|
|
765
807
|
}
|
|
808
|
+
.transition-opacity {
|
|
809
|
+
transition-property: opacity;
|
|
810
|
+
transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
|
|
811
|
+
transition-duration: var(--tw-duration, var(--default-transition-duration));
|
|
812
|
+
}
|
|
766
813
|
.transition-transform {
|
|
767
814
|
transition-property: transform, translate, scale, rotate;
|
|
768
815
|
transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
|
|
@@ -780,6 +827,11 @@
|
|
|
780
827
|
}
|
|
781
828
|
}
|
|
782
829
|
}
|
|
830
|
+
.first\:pt-0 {
|
|
831
|
+
&:first-child {
|
|
832
|
+
padding-top: calc(var(--spacing) * 0);
|
|
833
|
+
}
|
|
834
|
+
}
|
|
783
835
|
.hover\:text-amber-600 {
|
|
784
836
|
&:hover {
|
|
785
837
|
@media (hover: hover) {
|
|
@@ -815,6 +867,13 @@
|
|
|
815
867
|
}
|
|
816
868
|
}
|
|
817
869
|
}
|
|
870
|
+
.hover\:opacity-100 {
|
|
871
|
+
&:hover {
|
|
872
|
+
@media (hover: hover) {
|
|
873
|
+
opacity: 100%;
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
}
|
|
818
877
|
.focus\:border-amber-500 {
|
|
819
878
|
&:focus {
|
|
820
879
|
border-color: var(--color-amber-500);
|
|
@@ -1027,59 +1086,6 @@ body {
|
|
|
1027
1086
|
inherits: false;
|
|
1028
1087
|
initial-value: 0 0 #0000;
|
|
1029
1088
|
}
|
|
1030
|
-
@property --tw-blur {
|
|
1031
|
-
syntax: "*";
|
|
1032
|
-
inherits: false;
|
|
1033
|
-
}
|
|
1034
|
-
@property --tw-brightness {
|
|
1035
|
-
syntax: "*";
|
|
1036
|
-
inherits: false;
|
|
1037
|
-
}
|
|
1038
|
-
@property --tw-contrast {
|
|
1039
|
-
syntax: "*";
|
|
1040
|
-
inherits: false;
|
|
1041
|
-
}
|
|
1042
|
-
@property --tw-grayscale {
|
|
1043
|
-
syntax: "*";
|
|
1044
|
-
inherits: false;
|
|
1045
|
-
}
|
|
1046
|
-
@property --tw-hue-rotate {
|
|
1047
|
-
syntax: "*";
|
|
1048
|
-
inherits: false;
|
|
1049
|
-
}
|
|
1050
|
-
@property --tw-invert {
|
|
1051
|
-
syntax: "*";
|
|
1052
|
-
inherits: false;
|
|
1053
|
-
}
|
|
1054
|
-
@property --tw-opacity {
|
|
1055
|
-
syntax: "*";
|
|
1056
|
-
inherits: false;
|
|
1057
|
-
}
|
|
1058
|
-
@property --tw-saturate {
|
|
1059
|
-
syntax: "*";
|
|
1060
|
-
inherits: false;
|
|
1061
|
-
}
|
|
1062
|
-
@property --tw-sepia {
|
|
1063
|
-
syntax: "*";
|
|
1064
|
-
inherits: false;
|
|
1065
|
-
}
|
|
1066
|
-
@property --tw-drop-shadow {
|
|
1067
|
-
syntax: "*";
|
|
1068
|
-
inherits: false;
|
|
1069
|
-
}
|
|
1070
|
-
@property --tw-drop-shadow-color {
|
|
1071
|
-
syntax: "*";
|
|
1072
|
-
inherits: false;
|
|
1073
|
-
}
|
|
1074
|
-
@property --tw-drop-shadow-alpha {
|
|
1075
|
-
syntax: "<percentage>";
|
|
1076
|
-
inherits: false;
|
|
1077
|
-
initial-value: 100%;
|
|
1078
|
-
}
|
|
1079
|
-
@property --tw-drop-shadow-size {
|
|
1080
|
-
syntax: "*";
|
|
1081
|
-
inherits: false;
|
|
1082
|
-
}
|
|
1083
1089
|
@keyframes pulse {
|
|
1084
1090
|
50% {
|
|
1085
1091
|
opacity: 0.5;
|
|
@@ -1110,19 +1116,6 @@ body {
|
|
|
1110
1116
|
--tw-ring-offset-width: 0px;
|
|
1111
1117
|
--tw-ring-offset-color: #fff;
|
|
1112
1118
|
--tw-ring-offset-shadow: 0 0 #0000;
|
|
1113
|
-
--tw-blur: initial;
|
|
1114
|
-
--tw-brightness: initial;
|
|
1115
|
-
--tw-contrast: initial;
|
|
1116
|
-
--tw-grayscale: initial;
|
|
1117
|
-
--tw-hue-rotate: initial;
|
|
1118
|
-
--tw-invert: initial;
|
|
1119
|
-
--tw-opacity: initial;
|
|
1120
|
-
--tw-saturate: initial;
|
|
1121
|
-
--tw-sepia: initial;
|
|
1122
|
-
--tw-drop-shadow: initial;
|
|
1123
|
-
--tw-drop-shadow-color: initial;
|
|
1124
|
-
--tw-drop-shadow-alpha: 100%;
|
|
1125
|
-
--tw-drop-shadow-size: initial;
|
|
1126
1119
|
}
|
|
1127
1120
|
}
|
|
1128
1121
|
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Protege
|
|
4
|
+
# Shared concern for controllers nested under an agent.
|
|
5
|
+
# Sets +@agent+ from +params[:agent_id]+.
|
|
6
|
+
module AgentScoped
|
|
7
|
+
extend ActiveSupport::Concern
|
|
8
|
+
|
|
9
|
+
included do
|
|
10
|
+
before_action :set_agent
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
private
|
|
14
|
+
|
|
15
|
+
# Load the +Agent+ named by +params[:agent_id]+ into +@agent+.
|
|
16
|
+
#
|
|
17
|
+
# @return [Protege::Agent] the loaded agent
|
|
18
|
+
def set_agent
|
|
19
|
+
@agent = Agent.find(params[:agent_id])
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Protege
|
|
4
|
+
# Shared concern for controllers nested under a toolkit grant.
|
|
5
|
+
# Sets +@agent_toolkit+ from +params[:agent_toolkit_id]+.
|
|
6
|
+
module AgentToolkitScoped
|
|
7
|
+
extend ActiveSupport::Concern
|
|
8
|
+
|
|
9
|
+
included do
|
|
10
|
+
before_action :set_agent_toolkit
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
private
|
|
14
|
+
|
|
15
|
+
# Load the +AgentToolkit+ named by +params[:agent_toolkit_id]+ into +@agent_toolkit+.
|
|
16
|
+
#
|
|
17
|
+
# @return [Protege::AgentToolkit] the loaded grant
|
|
18
|
+
def set_agent_toolkit
|
|
19
|
+
@agent_toolkit = AgentToolkit.find(params[:agent_toolkit_id])
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -1,35 +1,35 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Protege
|
|
4
|
-
# Manages
|
|
5
|
-
# access guardrail (see +AccessRule+ and +AccessControl+). Nested under
|
|
6
|
-
# +
|
|
7
|
-
# action renders back to the
|
|
4
|
+
# Manages an agent's runtime inbound access rules — the dashboard-editable, narrowing layer of the
|
|
5
|
+
# access guardrail (see +AccessRule+ and +AccessControl+). Nested under agents via the
|
|
6
|
+
# +AgentScoped+ concern, which loads +@agent+ from +params[:agent_id]+ before every action; each
|
|
7
|
+
# action renders back to the agent's page.
|
|
8
8
|
class AccessRulesController < ApplicationController
|
|
9
|
-
include
|
|
9
|
+
include AgentScoped
|
|
10
10
|
|
|
11
11
|
before_action :set_access_rule, only: [:destroy]
|
|
12
12
|
|
|
13
|
-
# Add an access rule to the
|
|
13
|
+
# Add an access rule to the agent. Serves +POST /agents/:agent_id/access_rules+.
|
|
14
14
|
#
|
|
15
15
|
# Turbo requests update the rules table in place (append the row + reset the form on success, or
|
|
16
16
|
# re-render the form with errors); non-Turbo requests redirect back with the result in the flash.
|
|
17
17
|
#
|
|
18
18
|
# @return [void]
|
|
19
19
|
def create
|
|
20
|
-
@access_rule = @
|
|
20
|
+
@access_rule = @agent.access_rules.build(access_rule_params)
|
|
21
21
|
saved = @access_rule.save
|
|
22
22
|
|
|
23
23
|
respond_to do |format|
|
|
24
24
|
format.turbo_stream { render :create, status: saved ? :ok : :unprocessable_entity }
|
|
25
|
-
format.html { redirect_to
|
|
25
|
+
format.html { redirect_to agent_path(@agent), **create_flash(saved) }
|
|
26
26
|
end
|
|
27
27
|
end
|
|
28
28
|
|
|
29
|
-
# Remove an access rule from the
|
|
30
|
-
# +DELETE /
|
|
29
|
+
# Remove an access rule from the agent. Serves
|
|
30
|
+
# +DELETE /agents/:agent_id/access_rules/:id+.
|
|
31
31
|
#
|
|
32
|
-
# Turbo requests remove the row in place; non-Turbo requests redirect back to the
|
|
32
|
+
# Turbo requests remove the row in place; non-Turbo requests redirect back to the agent.
|
|
33
33
|
#
|
|
34
34
|
# @return [void]
|
|
35
35
|
def destroy
|
|
@@ -37,7 +37,7 @@ module Protege
|
|
|
37
37
|
|
|
38
38
|
respond_to do |format|
|
|
39
39
|
format.turbo_stream { render turbo_stream: turbo_stream.remove(@access_rule) }
|
|
40
|
-
format.html { redirect_to
|
|
40
|
+
format.html { redirect_to agent_path(@agent), notice: 'Access rule removed.' }
|
|
41
41
|
end
|
|
42
42
|
end
|
|
43
43
|
|
|
@@ -59,7 +59,7 @@ module Protege
|
|
|
59
59
|
#
|
|
60
60
|
# @return [Protege::AccessRule] the access rule to destroy
|
|
61
61
|
def set_access_rule
|
|
62
|
-
@access_rule = @
|
|
62
|
+
@access_rule = @agent.access_rules.find(params[:id])
|
|
63
63
|
end
|
|
64
64
|
|
|
65
65
|
# Permit the rule's kind and address pattern.
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Protege
|
|
4
|
+
# Manages a toolkit grant's allow/deny gate rules — the sender gate for one agent's copy of a toolkit.
|
|
5
|
+
# Nested under the grant via the +AgentToolkitScoped+ concern (which loads +@agent_toolkit+); mirrors
|
|
6
|
+
# +AccessRulesController+ (Turbo child rows), rendering back to the grant's page.
|
|
7
|
+
class AgentToolkitRulesController < ApplicationController
|
|
8
|
+
include AgentToolkitScoped
|
|
9
|
+
|
|
10
|
+
before_action :set_rule, only: [:destroy]
|
|
11
|
+
|
|
12
|
+
# Add a gate rule to the grant. Turbo requests append the row and reset the form; non-Turbo requests
|
|
13
|
+
# redirect back to the grant.
|
|
14
|
+
#
|
|
15
|
+
# @return [void]
|
|
16
|
+
def create
|
|
17
|
+
@agent_toolkit_rule = @agent_toolkit.agent_toolkit_rules.build(rule_params)
|
|
18
|
+
saved = @agent_toolkit_rule.save
|
|
19
|
+
|
|
20
|
+
respond_to do |format|
|
|
21
|
+
format.turbo_stream { render :create, status: saved ? :ok : :unprocessable_entity }
|
|
22
|
+
format.html { redirect_to agent_toolkit_path(@agent_toolkit), **create_flash(saved) }
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Remove a gate rule from the grant. Turbo requests remove the row in place.
|
|
27
|
+
#
|
|
28
|
+
# @return [void]
|
|
29
|
+
def destroy
|
|
30
|
+
@agent_toolkit_rule.destroy
|
|
31
|
+
|
|
32
|
+
respond_to do |format|
|
|
33
|
+
format.turbo_stream { render turbo_stream: turbo_stream.remove(@agent_toolkit_rule) }
|
|
34
|
+
format.html { redirect_to agent_toolkit_path(@agent_toolkit), notice: 'Rule removed.' }
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
private
|
|
39
|
+
|
|
40
|
+
# Load the rule to destroy, scoped to the grant.
|
|
41
|
+
#
|
|
42
|
+
# @return [Protege::AgentToolkitRule] the rule
|
|
43
|
+
def set_rule
|
|
44
|
+
@agent_toolkit_rule = @agent_toolkit.agent_toolkit_rules.find(params[:id])
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# The flash for the non-Turbo create redirect — a success notice, or the validation errors.
|
|
48
|
+
#
|
|
49
|
+
# @param saved [Boolean] whether the rule saved
|
|
50
|
+
# @return [Hash] the +redirect_to+ flash options
|
|
51
|
+
def create_flash(saved)
|
|
52
|
+
saved ? { notice: 'Rule added.' } : { alert: @agent_toolkit_rule.errors.full_messages.to_sentence }
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Permit the rule's kind and address pattern.
|
|
56
|
+
#
|
|
57
|
+
# @return [ActionController::Parameters] the permitted +:kind+ and +:pattern+
|
|
58
|
+
def rule_params
|
|
59
|
+
params.require(:agent_toolkit_rule).permit(:kind, :pattern)
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Protege
|
|
4
|
+
# Manages a created toolkit grant — the page where you configure how one agent uses one toolkit: its
|
|
5
|
+
# proactive flag and its sender-gate rules (the rules nest under this via +AgentToolkitRulesController+).
|
|
6
|
+
# Top-level and keyed by the grant's own id, so nesting never goes two deep. Attaching/detaching grants
|
|
7
|
+
# lives in the nested +Agents::AgentToolkitsController+.
|
|
8
|
+
class AgentToolkitsController < ApplicationController
|
|
9
|
+
before_action :set_agent_toolkit
|
|
10
|
+
|
|
11
|
+
# Show the grant's configuration page (its toolkit's tools, proactive flag, and gate rules).
|
|
12
|
+
#
|
|
13
|
+
# @return [void]
|
|
14
|
+
def show; end
|
|
15
|
+
|
|
16
|
+
# Update the grant's proactive flag. On failure, re-render its page.
|
|
17
|
+
#
|
|
18
|
+
# @return [void]
|
|
19
|
+
def update
|
|
20
|
+
if @agent_toolkit.update(agent_toolkit_params)
|
|
21
|
+
redirect_to agent_toolkit_path(@agent_toolkit), notice: 'Grant updated.'
|
|
22
|
+
else
|
|
23
|
+
render :show, status: :unprocessable_entity
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
private
|
|
28
|
+
|
|
29
|
+
# Load the grant named by the route.
|
|
30
|
+
#
|
|
31
|
+
# @return [Protege::AgentToolkit] the grant
|
|
32
|
+
def set_agent_toolkit
|
|
33
|
+
@agent_toolkit = AgentToolkit.find(params[:id])
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Permit the grant's editable attributes — only the proactive flag; the tool set is the toolkit's and
|
|
37
|
+
# the gate is edited as child rules.
|
|
38
|
+
#
|
|
39
|
+
# @return [ActionController::Parameters] the permitted attributes
|
|
40
|
+
def agent_toolkit_params
|
|
41
|
+
params.require(:agent_toolkit).permit(:allow_proactive)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Protege
|
|
4
|
+
module Agents
|
|
5
|
+
# Attaches and detaches an agent's toolkit grants — the list of toolkits given to one agent, in the
|
|
6
|
+
# agent's scope. Nested under agents via +AgentScoped+; mirrors +AccessRulesController+ (Turbo
|
|
7
|
+
# child rows), rendering back to the agent's page. Managing a created grant (its gate, proactive
|
|
8
|
+
# flag, rules) is the top-level +AgentToolkitsController+.
|
|
9
|
+
class AgentToolkitsController < ApplicationController
|
|
10
|
+
include AgentScoped
|
|
11
|
+
|
|
12
|
+
before_action :set_agent_toolkit, only: [:destroy]
|
|
13
|
+
|
|
14
|
+
# Attach a toolkit to the agent. Turbo requests append the grant row and reset the form; non-Turbo
|
|
15
|
+
# requests redirect back to the agent.
|
|
16
|
+
#
|
|
17
|
+
# @return [void]
|
|
18
|
+
def create
|
|
19
|
+
@agent_toolkit = @agent.agent_toolkits.build(agent_toolkit_params)
|
|
20
|
+
saved = @agent_toolkit.save
|
|
21
|
+
|
|
22
|
+
respond_to do |format|
|
|
23
|
+
format.turbo_stream { render :create, status: saved ? :ok : :unprocessable_entity }
|
|
24
|
+
format.html { redirect_to agent_path(@agent), **create_flash(saved) }
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Detach a toolkit from the agent. Turbo requests remove the row in place.
|
|
29
|
+
#
|
|
30
|
+
# @return [void]
|
|
31
|
+
def destroy
|
|
32
|
+
@agent_toolkit.destroy
|
|
33
|
+
|
|
34
|
+
respond_to do |format|
|
|
35
|
+
format.turbo_stream { render turbo_stream: turbo_stream.remove(@agent_toolkit) }
|
|
36
|
+
format.html { redirect_to agent_path(@agent), notice: 'Toolkit detached.' }
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
private
|
|
41
|
+
|
|
42
|
+
# Load the grant to destroy, scoped to the agent.
|
|
43
|
+
#
|
|
44
|
+
# @return [Protege::AgentToolkit] the grant
|
|
45
|
+
def set_agent_toolkit
|
|
46
|
+
@agent_toolkit = @agent.agent_toolkits.find(params[:id])
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# The flash for the non-Turbo create redirect — a success notice, or the validation errors.
|
|
50
|
+
#
|
|
51
|
+
# @param saved [Boolean] whether the grant saved
|
|
52
|
+
# @return [Hash] the +redirect_to+ flash options
|
|
53
|
+
def create_flash(saved)
|
|
54
|
+
saved ? { notice: 'Toolkit attached.' } : { alert: @agent_toolkit.errors.full_messages.to_sentence }
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Permit the toolkit being attached.
|
|
58
|
+
#
|
|
59
|
+
# @return [ActionController::Parameters] the permitted +:toolkit_id+
|
|
60
|
+
def agent_toolkit_params
|
|
61
|
+
params.require(:agent_toolkit).permit(:toolkit_id)
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|