prompt_objects 0.1.0 → 0.2.0
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/frontend/src/App.tsx +2 -1
- data/frontend/src/components/CapabilitiesPanel.tsx +122 -25
- data/frontend/src/components/ChatPanel.tsx +43 -6
- data/frontend/src/components/PODetail.tsx +8 -1
- data/frontend/src/components/PromptPanel.tsx +124 -19
- data/frontend/src/hooks/useWebSocket.ts +16 -0
- data/frontend/src/types/index.ts +12 -1
- data/lib/prompt_objects/environment.rb +11 -0
- data/lib/prompt_objects/prompt_object.rb +10 -0
- data/lib/prompt_objects/server/public/assets/index-CeNJvqLG.js +77 -0
- data/lib/prompt_objects/server/public/assets/index-Vx4-uMOU.css +1 -0
- data/lib/prompt_objects/server/public/index.html +2 -2
- data/lib/prompt_objects/server/websocket_handler.rb +67 -3
- data/lib/prompt_objects/server.rb +13 -0
- data/lib/prompt_objects/universal/add_capability.rb +6 -1
- data/lib/prompt_objects/universal/add_primitive.rb +6 -1
- data/lib/prompt_objects/universal/create_capability.rb +4 -0
- data/lib/prompt_objects/universal/create_primitive.rb +4 -0
- data/lib/prompt_objects/universal/delete_primitive.rb +77 -0
- data/lib/prompt_objects/universal/modify_prompt.rb +164 -0
- data/lib/prompt_objects/universal/remove_capability.rb +73 -0
- data/lib/prompt_objects.rb +4 -1
- data/prompt_objects.gemspec +1 -1
- metadata +6 -3
- data/lib/prompt_objects/server/public/assets/index-2acS2FYZ.js +0 -77
- data/lib/prompt_objects/server/public/assets/index-DXU5uRXQ.css +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.-right-1{right:-.25rem}.-top-1{top:-.25rem}.bottom-4{bottom:1rem}.left-2{left:.5rem}.right-0{right:0}.right-4{right:1rem}.top-0{top:0}.top-16{top:4rem}.top-full{top:100%}.z-10{z-index:10}.z-50{z-index:50}.my-3{margin-top:.75rem;margin-bottom:.75rem}.my-4{margin-top:1rem;margin-bottom:1rem}.-mb-px{margin-bottom:-1px}.mb-1{margin-bottom:.25rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.mb-6{margin-bottom:1.5rem}.ml-1{margin-left:.25rem}.ml-11{margin-left:2.75rem}.ml-2{margin-left:.5rem}.ml-3{margin-left:.75rem}.ml-auto{margin-left:auto}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.mt-6{margin-top:1.5rem}.line-clamp-2{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2}.inline-block{display:inline-block}.flex{display:flex}.table{display:table}.grid{display:grid}.hidden{display:none}.h-1\.5{height:.375rem}.h-14{height:3.5rem}.h-2{height:.5rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-8{height:2rem}.h-96{height:24rem}.h-full{height:100%}.h-screen{height:100vh}.max-h-64{max-height:16rem}.max-h-\[60vh\]{max-height:60vh}.w-1\.5{width:.375rem}.w-2{width:.5rem}.w-4{width:1rem}.w-5{width:1.25rem}.w-56{width:14rem}.w-64{width:16rem}.w-8{width:2rem}.w-80{width:20rem}.w-96{width:24rem}.w-full{width:100%}.min-w-full{min-width:100%}.max-w-\[80\%\]{max-width:80%}.max-w-none{max-width:none}.flex-1{flex:1 1 0%}.flex-shrink-0{flex-shrink:0}.rotate-180{--tw-rotate: 180deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes bounce{0%,to{transform:translateY(-25%);animation-timing-function:cubic-bezier(.8,0,1,1)}50%{transform:none;animation-timing-function:cubic-bezier(0,0,.2,1)}}.animate-bounce{animation:bounce 1s infinite}@keyframes pulse{50%{opacity:.5}}.animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.resize-none{resize:none}.list-inside{list-style-position:inside}.list-decimal{list-style-type:decimal}.list-disc{list-style-type:disc}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.flex-row-reverse{flex-direction:row-reverse}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-center{align-items:center}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-1{gap:.25rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem * var(--tw-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.75rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem * var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.rounded{border-radius:.25rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-t{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.border{border-width:1px}.border-b{border-bottom-width:1px}.border-b-0{border-bottom-width:0px}.border-b-2{border-bottom-width:2px}.border-l{border-left-width:1px}.border-l-4{border-left-width:4px}.border-r{border-right-width:1px}.border-t{border-top-width:1px}.border-po-accent{--tw-border-opacity: 1;border-color:rgb(124 58 237 / var(--tw-border-opacity, 1))}.border-po-border{--tw-border-opacity: 1;border-color:rgb(45 45 68 / var(--tw-border-opacity, 1))}.border-po-border\/30{border-color:#2d2d444d}.border-po-border\/50{border-color:#2d2d4480}.border-po-warning\/30{border-color:#f59e0b4d}.border-transparent{border-color:transparent}.bg-blue-600\/30{background-color:#2563eb4d}.bg-gray-500{--tw-bg-opacity: 1;background-color:rgb(107 114 128 / var(--tw-bg-opacity, 1))}.bg-gray-600\/30{background-color:#4b55634d}.bg-green-500{--tw-bg-opacity: 1;background-color:rgb(34 197 94 / var(--tw-bg-opacity, 1))}.bg-green-600{--tw-bg-opacity: 1;background-color:rgb(22 163 74 / var(--tw-bg-opacity, 1))}.bg-po-accent{--tw-bg-opacity: 1;background-color:rgb(124 58 237 / var(--tw-bg-opacity, 1))}.bg-po-accent\/20{background-color:#7c3aed33}.bg-po-bg{--tw-bg-opacity: 1;background-color:rgb(15 15 26 / var(--tw-bg-opacity, 1))}.bg-po-bg\/50{background-color:#0f0f1a80}.bg-po-bg\/80{background-color:#0f0f1acc}.bg-po-border{--tw-bg-opacity: 1;background-color:rgb(45 45 68 / var(--tw-bg-opacity, 1))}.bg-po-surface{--tw-bg-opacity: 1;background-color:rgb(26 26 46 / var(--tw-bg-opacity, 1))}.bg-po-surface\/50{background-color:#1a1a2e80}.bg-po-warning{--tw-bg-opacity: 1;background-color:rgb(245 158 11 / var(--tw-bg-opacity, 1))}.bg-po-warning\/10{background-color:#f59e0b1a}.bg-purple-600\/30{background-color:#9333ea4d}.bg-red-500{--tw-bg-opacity: 1;background-color:rgb(239 68 68 / var(--tw-bg-opacity, 1))}.bg-transparent{background-color:transparent}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-6{padding:1.5rem}.px-1\.5{padding-left:.375rem;padding-right:.375rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-8{padding-top:2rem;padding-bottom:2rem}.pb-1{padding-bottom:.25rem}.pb-2{padding-bottom:.5rem}.pl-4{padding-left:1rem}.text-left{text-align:left}.text-center{text-align:center}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-2xl{font-size:1.5rem;line-height:2rem}.text-4xl{font-size:2.25rem;line-height:2.5rem}.text-\[10px\]{font-size:10px}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.normal-case{text-transform:none}.italic{font-style:italic}.leading-relaxed{line-height:1.625}.tracking-wide{letter-spacing:.025em}.text-black{--tw-text-opacity: 1;color:rgb(0 0 0 / var(--tw-text-opacity, 1))}.text-blue-300{--tw-text-opacity: 1;color:rgb(147 197 253 / var(--tw-text-opacity, 1))}.text-blue-400{--tw-text-opacity: 1;color:rgb(96 165 250 / var(--tw-text-opacity, 1))}.text-gray-100{--tw-text-opacity: 1;color:rgb(243 244 246 / var(--tw-text-opacity, 1))}.text-gray-200{--tw-text-opacity: 1;color:rgb(229 231 235 / var(--tw-text-opacity, 1))}.text-gray-300{--tw-text-opacity: 1;color:rgb(209 213 219 / var(--tw-text-opacity, 1))}.text-gray-400{--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.text-gray-500{--tw-text-opacity: 1;color:rgb(107 114 128 / var(--tw-text-opacity, 1))}.text-gray-600{--tw-text-opacity: 1;color:rgb(75 85 99 / var(--tw-text-opacity, 1))}.text-green-400{--tw-text-opacity: 1;color:rgb(74 222 128 / var(--tw-text-opacity, 1))}.text-po-accent{--tw-text-opacity: 1;color:rgb(124 58 237 / var(--tw-text-opacity, 1))}.text-po-accent\/70{color:#7c3aedb3}.text-po-warning{--tw-text-opacity: 1;color:rgb(245 158 11 / var(--tw-text-opacity, 1))}.text-purple-300{--tw-text-opacity: 1;color:rgb(216 180 254 / var(--tw-text-opacity, 1))}.text-purple-400{--tw-text-opacity: 1;color:rgb(192 132 252 / var(--tw-text-opacity, 1))}.text-red-400{--tw-text-opacity: 1;color:rgb(248 113 113 / var(--tw-text-opacity, 1))}.text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.text-yellow-400{--tw-text-opacity: 1;color:rgb(250 204 21 / var(--tw-text-opacity, 1))}.placeholder-gray-500::-moz-placeholder{--tw-placeholder-opacity: 1;color:rgb(107 114 128 / var(--tw-placeholder-opacity, 1))}.placeholder-gray-500::placeholder{--tw-placeholder-opacity: 1;color:rgb(107 114 128 / var(--tw-placeholder-opacity, 1))}.shadow-xl{--tw-shadow: 0 20px 25px -5px rgb(0 0 0 / .1), 0 8px 10px -6px rgb(0 0 0 / .1);--tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.filter{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)}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}html{color-scheme:dark}body{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}::-webkit-scrollbar{width:8px;height:8px}::-webkit-scrollbar-track{--tw-bg-opacity: 1;background-color:rgb(15 15 26 / var(--tw-bg-opacity, 1))}::-webkit-scrollbar-thumb{border-radius:9999px;--tw-bg-opacity: 1;background-color:rgb(45 45 68 / var(--tw-bg-opacity, 1))}::-webkit-scrollbar-thumb:hover{--tw-bg-opacity: 1;background-color:rgb(124 58 237 / var(--tw-bg-opacity, 1))}.first\:mt-0:first-child{margin-top:0}.last\:mb-0:last-child{margin-bottom:0}.last\:border-0:last-child{border-width:0px}.hover\:border-po-accent:hover{--tw-border-opacity: 1;border-color:rgb(124 58 237 / var(--tw-border-opacity, 1))}.hover\:border-po-accent\/50:hover{border-color:#7c3aed80}.hover\:bg-po-accent\/50:hover{background-color:#7c3aed80}.hover\:bg-po-accent\/80:hover{background-color:#7c3aedcc}.hover\:bg-po-bg:hover{--tw-bg-opacity: 1;background-color:rgb(15 15 26 / var(--tw-bg-opacity, 1))}.hover\:bg-po-bg\/70:hover{background-color:#0f0f1ab3}.hover\:bg-po-border:hover{--tw-bg-opacity: 1;background-color:rgb(45 45 68 / var(--tw-bg-opacity, 1))}.hover\:bg-po-surface:hover{--tw-bg-opacity: 1;background-color:rgb(26 26 46 / var(--tw-bg-opacity, 1))}.hover\:bg-po-warning\/20:hover{background-color:#f59e0b33}.hover\:text-po-accent:hover{--tw-text-opacity: 1;color:rgb(124 58 237 / var(--tw-text-opacity, 1))}.hover\:text-white:hover{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.hover\:underline:hover{text-decoration-line:underline}.focus\:border-po-accent:focus{--tw-border-opacity: 1;border-color:rgb(124 58 237 / var(--tw-border-opacity, 1))}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-1:focus{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus\:ring-po-accent:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(124 58 237 / var(--tw-ring-opacity, 1))}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}.group:hover .group-hover\:text-po-accent{--tw-text-opacity: 1;color:rgb(124 58 237 / var(--tw-text-opacity, 1))}@media(min-width:768px){.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media(min-width:1024px){.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}}@media(min-width:1280px){.xl\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}}
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
7
|
<title>PromptObjects</title>
|
|
8
|
-
<script type="module" crossorigin src="/assets/index-
|
|
9
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
8
|
+
<script type="module" crossorigin src="/assets/index-CeNJvqLG.js"></script>
|
|
9
|
+
<link rel="stylesheet" crossorigin href="/assets/index-Vx4-uMOU.css">
|
|
10
10
|
</head>
|
|
11
11
|
<body class="bg-po-bg text-gray-100">
|
|
12
12
|
<div id="root"></div>
|
|
@@ -219,6 +219,8 @@ module PromptObjects
|
|
|
219
219
|
handle_get_llm_config
|
|
220
220
|
when "switch_llm"
|
|
221
221
|
handle_switch_llm(message["payload"])
|
|
222
|
+
when "update_prompt"
|
|
223
|
+
handle_update_prompt(message["payload"])
|
|
222
224
|
when "ping"
|
|
223
225
|
send_message(type: "pong", payload: {})
|
|
224
226
|
else
|
|
@@ -295,9 +297,20 @@ module PromptObjects
|
|
|
295
297
|
context = @runtime.context(tui_mode: true)
|
|
296
298
|
context.current_capability = "human"
|
|
297
299
|
|
|
300
|
+
# Set up callback for real-time tool call updates
|
|
301
|
+
# This fires after each tool call iteration in the receive loop
|
|
302
|
+
po.on_history_updated = ->(po_obj, session_id, history) {
|
|
303
|
+
send_message(
|
|
304
|
+
type: "session_updated",
|
|
305
|
+
payload: {
|
|
306
|
+
target: po_obj.name,
|
|
307
|
+
session_id: session_id,
|
|
308
|
+
messages: history.map { |m| message_to_hash(m) }
|
|
309
|
+
}
|
|
310
|
+
)
|
|
311
|
+
}
|
|
312
|
+
|
|
298
313
|
begin
|
|
299
|
-
# TODO: Add streaming support to receive()
|
|
300
|
-
# For now, just get the full response
|
|
301
314
|
response = po.receive(content, context: context)
|
|
302
315
|
|
|
303
316
|
# Auto-name the thread if it doesn't have a name yet
|
|
@@ -337,6 +350,9 @@ module PromptObjects
|
|
|
337
350
|
rescue => e
|
|
338
351
|
send_error("Error from #{po_name}: #{e.message}")
|
|
339
352
|
ensure
|
|
353
|
+
# Clean up the callback
|
|
354
|
+
po.on_history_updated = nil
|
|
355
|
+
|
|
340
356
|
# Update PO state back to idle (status only, not session data)
|
|
341
357
|
send_message(
|
|
342
358
|
type: "po_state",
|
|
@@ -523,6 +539,30 @@ module PromptObjects
|
|
|
523
539
|
end
|
|
524
540
|
end
|
|
525
541
|
|
|
542
|
+
def handle_update_prompt(payload)
|
|
543
|
+
po_name = payload["target"]
|
|
544
|
+
new_prompt = payload["prompt"]
|
|
545
|
+
|
|
546
|
+
po = @runtime.registry.get(po_name)
|
|
547
|
+
return send_error("Unknown prompt object: #{po_name}") unless po.is_a?(PromptObject)
|
|
548
|
+
|
|
549
|
+
# Update the body in memory
|
|
550
|
+
po.instance_variable_set(:@body, new_prompt)
|
|
551
|
+
|
|
552
|
+
# Persist to file
|
|
553
|
+
if po.save
|
|
554
|
+
# Notify for real-time UI update (broadcasts to all clients)
|
|
555
|
+
@runtime.notify_po_modified(po)
|
|
556
|
+
|
|
557
|
+
send_message(
|
|
558
|
+
type: "prompt_updated",
|
|
559
|
+
payload: { target: po_name, success: true }
|
|
560
|
+
)
|
|
561
|
+
else
|
|
562
|
+
send_error("Failed to save prompt for #{po_name}")
|
|
563
|
+
end
|
|
564
|
+
end
|
|
565
|
+
|
|
526
566
|
# === Helpers ===
|
|
527
567
|
|
|
528
568
|
def send_error(message)
|
|
@@ -533,7 +573,8 @@ module PromptObjects
|
|
|
533
573
|
{
|
|
534
574
|
status: po.instance_variable_get(:@state) || "idle",
|
|
535
575
|
description: po.description,
|
|
536
|
-
capabilities: po
|
|
576
|
+
capabilities: declared_capabilities_info(po),
|
|
577
|
+
universal_capabilities: universal_capabilities_info,
|
|
537
578
|
current_session: current_session_hash(po),
|
|
538
579
|
sessions: po.list_sessions.map { |s| session_summary(s) },
|
|
539
580
|
# Include full prompt for inspection
|
|
@@ -542,6 +583,29 @@ module PromptObjects
|
|
|
542
583
|
}
|
|
543
584
|
end
|
|
544
585
|
|
|
586
|
+
def declared_capabilities_info(po)
|
|
587
|
+
declared = po.config["capabilities"] || []
|
|
588
|
+
declared.map do |name|
|
|
589
|
+
cap = @runtime.registry.get(name)
|
|
590
|
+
{
|
|
591
|
+
name: name,
|
|
592
|
+
description: cap&.description || "Capability not found",
|
|
593
|
+
parameters: cap&.parameters
|
|
594
|
+
}
|
|
595
|
+
end
|
|
596
|
+
end
|
|
597
|
+
|
|
598
|
+
def universal_capabilities_info
|
|
599
|
+
UNIVERSAL_CAPABILITIES.map do |name|
|
|
600
|
+
cap = @runtime.registry.get(name)
|
|
601
|
+
{
|
|
602
|
+
name: name,
|
|
603
|
+
description: cap&.description || "Universal capability",
|
|
604
|
+
parameters: cap&.parameters
|
|
605
|
+
}
|
|
606
|
+
end
|
|
607
|
+
end
|
|
608
|
+
|
|
545
609
|
def current_session_hash(po)
|
|
546
610
|
return nil unless po.session_id
|
|
547
611
|
|
|
@@ -46,6 +46,19 @@ module PromptObjects
|
|
|
46
46
|
puts "Broadcast: PO registered - #{po.name}"
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
+
# Register callback for PO modification notifications
|
|
50
|
+
# This fires when capabilities are added/removed programmatically
|
|
51
|
+
runtime.on_po_modified = ->(po) {
|
|
52
|
+
app.broadcast(
|
|
53
|
+
type: "po_modified",
|
|
54
|
+
payload: {
|
|
55
|
+
name: po.name,
|
|
56
|
+
state: po_state_hash(po)
|
|
57
|
+
}
|
|
58
|
+
)
|
|
59
|
+
puts "Broadcast: PO modified (programmatic) - #{po.name}"
|
|
60
|
+
}
|
|
61
|
+
|
|
49
62
|
# Start file watcher for live updates (manual file edits)
|
|
50
63
|
file_watcher = nil
|
|
51
64
|
if env_path
|
|
@@ -63,7 +63,12 @@ module PromptObjects
|
|
|
63
63
|
target_po.config["capabilities"] << capability
|
|
64
64
|
|
|
65
65
|
# Persist to file so it's available on restart
|
|
66
|
-
|
|
66
|
+
saved = target_po.save
|
|
67
|
+
|
|
68
|
+
# Notify for real-time UI update (don't wait for file watcher)
|
|
69
|
+
context.env.notify_po_modified(target_po)
|
|
70
|
+
|
|
71
|
+
if saved
|
|
67
72
|
"Added '#{capability}' to '#{target}' and saved to file. It can now use this capability."
|
|
68
73
|
else
|
|
69
74
|
"Added '#{capability}' to '#{target}' (in-memory only, could not save to file). It can now use this capability."
|
|
@@ -69,7 +69,12 @@ module PromptObjects
|
|
|
69
69
|
target_po.config["capabilities"] << primitive_name
|
|
70
70
|
|
|
71
71
|
# Persist to file so it's available on restart
|
|
72
|
-
|
|
72
|
+
saved = target_po.save
|
|
73
|
+
|
|
74
|
+
# Notify for real-time UI update
|
|
75
|
+
context.env.notify_po_modified(target_po)
|
|
76
|
+
|
|
77
|
+
if saved
|
|
73
78
|
"Added '#{primitive_name}' to your capabilities and saved to file. You can now use it."
|
|
74
79
|
else
|
|
75
80
|
"Added '#{primitive_name}' to your capabilities (in-memory only). You can now use it."
|
|
@@ -110,6 +110,10 @@ module PromptObjects
|
|
|
110
110
|
creator_po.config["capabilities"] << cap_name
|
|
111
111
|
# Persist the change to file
|
|
112
112
|
saved = creator_po.save ? " and saved" : ""
|
|
113
|
+
|
|
114
|
+
# Notify for real-time UI update
|
|
115
|
+
context.env.notify_po_modified(creator_po)
|
|
116
|
+
|
|
113
117
|
return "Also added '#{cap_name}' to #{creator_name}'s capabilities#{saved}."
|
|
114
118
|
end
|
|
115
119
|
|
|
@@ -160,6 +160,10 @@ module PromptObjects
|
|
|
160
160
|
unless caller_po.config["capabilities"].include?(prim_name)
|
|
161
161
|
caller_po.config["capabilities"] << prim_name
|
|
162
162
|
saved = caller_po.save ? " and saved to file" : ""
|
|
163
|
+
|
|
164
|
+
# Notify for real-time UI update
|
|
165
|
+
context.env.notify_po_modified(caller_po)
|
|
166
|
+
|
|
163
167
|
return "Added '#{prim_name}' to your capabilities#{saved}."
|
|
164
168
|
end
|
|
165
169
|
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PromptObjects
|
|
4
|
+
module Universal
|
|
5
|
+
# Universal capability to delete a primitive file from the environment.
|
|
6
|
+
# This is for recovery when a broken primitive is causing problems.
|
|
7
|
+
# USE WITH CAUTION - this permanently deletes the primitive file.
|
|
8
|
+
class DeletePrimitive < Primitive
|
|
9
|
+
# Built-in primitives that cannot be deleted
|
|
10
|
+
PROTECTED_PRIMITIVES = %w[read_file list_files write_file http_get].freeze
|
|
11
|
+
|
|
12
|
+
def name
|
|
13
|
+
"delete_primitive"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def description
|
|
17
|
+
"Delete a primitive (Ruby tool) file from the environment. This is a DESTRUCTIVE operation - use for recovery when a broken primitive is causing problems. Cannot delete built-in primitives."
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def parameters
|
|
21
|
+
{
|
|
22
|
+
type: "object",
|
|
23
|
+
properties: {
|
|
24
|
+
primitive: {
|
|
25
|
+
type: "string",
|
|
26
|
+
description: "Name of the primitive to delete"
|
|
27
|
+
},
|
|
28
|
+
confirm: {
|
|
29
|
+
type: "boolean",
|
|
30
|
+
description: "Must be true to confirm deletion. This is a safety check."
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
required: ["primitive", "confirm"]
|
|
34
|
+
}
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def receive(message, context:)
|
|
38
|
+
primitive_name = message[:primitive] || message["primitive"]
|
|
39
|
+
confirm = message[:confirm] || message["confirm"]
|
|
40
|
+
|
|
41
|
+
# Safety check
|
|
42
|
+
unless confirm == true
|
|
43
|
+
return "Error: Must set confirm=true to delete a primitive. This is a destructive operation."
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Check if it's a protected primitive
|
|
47
|
+
if PROTECTED_PRIMITIVES.include?(primitive_name)
|
|
48
|
+
return "Error: Cannot delete built-in primitive '#{primitive_name}'."
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Check if it's a universal capability
|
|
52
|
+
if UNIVERSAL_CAPABILITIES.include?(primitive_name)
|
|
53
|
+
return "Error: Cannot delete universal capability '#{primitive_name}'."
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Find the primitive file
|
|
57
|
+
primitives_dir = context.env.primitives_dir
|
|
58
|
+
path = File.join(primitives_dir, "#{primitive_name}.rb")
|
|
59
|
+
|
|
60
|
+
unless File.exist?(path)
|
|
61
|
+
return "Error: Primitive file not found at #{path}. It may be a built-in primitive or not exist."
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# Unregister from registry first
|
|
65
|
+
context.env.registry.unregister(primitive_name)
|
|
66
|
+
|
|
67
|
+
# Delete the file
|
|
68
|
+
begin
|
|
69
|
+
File.delete(path)
|
|
70
|
+
"Deleted primitive '#{primitive_name}' and removed from registry. File: #{path}"
|
|
71
|
+
rescue => e
|
|
72
|
+
"Error deleting file: #{e.message}. Primitive was unregistered from memory."
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PromptObjects
|
|
4
|
+
module Universal
|
|
5
|
+
# Universal capability for POs to modify their own or other POs' markdown body (prompt).
|
|
6
|
+
# This enables self-modification of behavior, learning, and identity.
|
|
7
|
+
# Note: This does NOT modify the frontmatter (capabilities, etc.) - use add_capability for that.
|
|
8
|
+
class ModifyPrompt < Primitive
|
|
9
|
+
def name
|
|
10
|
+
"modify_prompt"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def description
|
|
14
|
+
"Modify a prompt object's markdown body (its identity/behavior prompt). Can append, prepend, replace sections, or do a full rewrite. Does NOT change capabilities - use add_capability for that."
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def parameters
|
|
18
|
+
{
|
|
19
|
+
type: "object",
|
|
20
|
+
properties: {
|
|
21
|
+
target: {
|
|
22
|
+
type: "string",
|
|
23
|
+
description: "Name of the prompt object to modify. Use 'self' for the current PO."
|
|
24
|
+
},
|
|
25
|
+
operation: {
|
|
26
|
+
type: "string",
|
|
27
|
+
enum: ["append", "prepend", "replace_section", "rewrite"],
|
|
28
|
+
description: "Type of modification: 'append' adds to end, 'prepend' adds to beginning, 'replace_section' replaces a specific section, 'rewrite' replaces the entire prompt"
|
|
29
|
+
},
|
|
30
|
+
content: {
|
|
31
|
+
type: "string",
|
|
32
|
+
description: "The new content to add or replace with"
|
|
33
|
+
},
|
|
34
|
+
section: {
|
|
35
|
+
type: "string",
|
|
36
|
+
description: "(For replace_section only) The section heading to replace (e.g., '## Learnings', '## Behavior'). The section and all content until the next heading of same or higher level will be replaced."
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
required: ["target", "operation", "content"]
|
|
40
|
+
}
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def receive(message, context:)
|
|
44
|
+
target = message[:target] || message["target"]
|
|
45
|
+
operation = message[:operation] || message["operation"]
|
|
46
|
+
content = message[:content] || message["content"]
|
|
47
|
+
section = message[:section] || message["section"]
|
|
48
|
+
|
|
49
|
+
# Resolve 'self' to the calling PO
|
|
50
|
+
target = context.calling_po if target == "self"
|
|
51
|
+
|
|
52
|
+
# Find the target PO
|
|
53
|
+
target_po = context.env.registry.get(target)
|
|
54
|
+
unless target_po
|
|
55
|
+
return "Error: Prompt object '#{target}' not found"
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
unless target_po.is_a?(PromptObject)
|
|
59
|
+
return "Error: '#{target}' is not a prompt object"
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Get current body
|
|
63
|
+
current_body = target_po.body || ""
|
|
64
|
+
|
|
65
|
+
# Apply the operation
|
|
66
|
+
new_body = case operation
|
|
67
|
+
when "append"
|
|
68
|
+
append_content(current_body, content)
|
|
69
|
+
when "prepend"
|
|
70
|
+
prepend_content(current_body, content)
|
|
71
|
+
when "replace_section"
|
|
72
|
+
unless section
|
|
73
|
+
return "Error: 'section' parameter required for replace_section operation"
|
|
74
|
+
end
|
|
75
|
+
replace_section(current_body, section, content)
|
|
76
|
+
when "rewrite"
|
|
77
|
+
content
|
|
78
|
+
else
|
|
79
|
+
return "Error: Unknown operation '#{operation}'. Use: append, prepend, replace_section, or rewrite"
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# Update the PO's body in memory
|
|
83
|
+
target_po.instance_variable_set(:@body, new_body)
|
|
84
|
+
|
|
85
|
+
# Persist to file
|
|
86
|
+
saved = target_po.save
|
|
87
|
+
|
|
88
|
+
# Notify for real-time UI update
|
|
89
|
+
context.env.notify_po_modified(target_po)
|
|
90
|
+
|
|
91
|
+
if saved
|
|
92
|
+
describe_change(operation, target, section)
|
|
93
|
+
else
|
|
94
|
+
"Modified '#{target}' prompt (in-memory only, could not save to file)."
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
private
|
|
99
|
+
|
|
100
|
+
def append_content(body, content)
|
|
101
|
+
body.empty? ? content : "#{body.rstrip}\n\n#{content}"
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def prepend_content(body, content)
|
|
105
|
+
body.empty? ? content : "#{content}\n\n#{body.lstrip}"
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def replace_section(body, section_heading, new_content)
|
|
109
|
+
# Normalize section heading (ensure it starts with #)
|
|
110
|
+
heading = section_heading.strip
|
|
111
|
+
heading = "## #{heading}" unless heading.start_with?("#")
|
|
112
|
+
|
|
113
|
+
# Determine heading level
|
|
114
|
+
heading_level = heading.match(/^(#+)/)[1].length
|
|
115
|
+
|
|
116
|
+
# Find the section
|
|
117
|
+
lines = body.lines
|
|
118
|
+
section_start = nil
|
|
119
|
+
section_end = nil
|
|
120
|
+
|
|
121
|
+
lines.each_with_index do |line, i|
|
|
122
|
+
if line.strip.downcase == heading.downcase || line.strip.downcase.start_with?("#{heading.downcase} ")
|
|
123
|
+
section_start = i
|
|
124
|
+
elsif section_start && !section_end
|
|
125
|
+
# Check if this is a heading of same or higher level
|
|
126
|
+
if line.match?(/^(#+)\s/)
|
|
127
|
+
line_level = line.match(/^(#+)/)[1].length
|
|
128
|
+
if line_level <= heading_level
|
|
129
|
+
section_end = i
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
unless section_start
|
|
136
|
+
# Section not found - append as new section
|
|
137
|
+
return append_content(body, "#{heading}\n\n#{new_content}")
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# If section_end not found, section goes to end of document
|
|
141
|
+
section_end ||= lines.length
|
|
142
|
+
|
|
143
|
+
# Build new body
|
|
144
|
+
before = lines[0...section_start].join
|
|
145
|
+
after = lines[section_end..].join
|
|
146
|
+
|
|
147
|
+
"#{before.rstrip}\n\n#{heading}\n\n#{new_content}\n\n#{after.lstrip}".strip
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def describe_change(operation, target, section)
|
|
151
|
+
case operation
|
|
152
|
+
when "append"
|
|
153
|
+
"Appended content to '#{target}' prompt and saved to file."
|
|
154
|
+
when "prepend"
|
|
155
|
+
"Prepended content to '#{target}' prompt and saved to file."
|
|
156
|
+
when "replace_section"
|
|
157
|
+
"Replaced section '#{section}' in '#{target}' prompt and saved to file."
|
|
158
|
+
when "rewrite"
|
|
159
|
+
"Rewrote '#{target}' prompt entirely and saved to file."
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
end
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PromptObjects
|
|
4
|
+
module Universal
|
|
5
|
+
# Universal capability to remove capabilities from a prompt object.
|
|
6
|
+
# Useful for cleanup or recovery when a capability is broken or no longer needed.
|
|
7
|
+
class RemoveCapability < Primitive
|
|
8
|
+
def name
|
|
9
|
+
"remove_capability"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def description
|
|
13
|
+
"Remove a capability from a prompt object. This removes it from the PO's declared capabilities but does NOT delete the underlying primitive/PO file. Use delete_primitive to fully remove a broken primitive."
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def parameters
|
|
17
|
+
{
|
|
18
|
+
type: "object",
|
|
19
|
+
properties: {
|
|
20
|
+
target: {
|
|
21
|
+
type: "string",
|
|
22
|
+
description: "Name of the prompt object to remove the capability from. Use 'self' for the current PO."
|
|
23
|
+
},
|
|
24
|
+
capability: {
|
|
25
|
+
type: "string",
|
|
26
|
+
description: "Name of the capability to remove"
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
required: ["target", "capability"]
|
|
30
|
+
}
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def receive(message, context:)
|
|
34
|
+
target = message[:target] || message["target"]
|
|
35
|
+
capability = message[:capability] || message["capability"]
|
|
36
|
+
|
|
37
|
+
# Resolve 'self' to the calling PO
|
|
38
|
+
target = context.calling_po if target == "self"
|
|
39
|
+
|
|
40
|
+
# Find the target PO
|
|
41
|
+
target_po = context.env.registry.get(target)
|
|
42
|
+
unless target_po
|
|
43
|
+
return "Error: Prompt object '#{target}' not found"
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
unless target_po.is_a?(PromptObject)
|
|
47
|
+
return "Error: '#{target}' is not a prompt object"
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Check if the capability is declared
|
|
51
|
+
current_caps = target_po.config["capabilities"] || []
|
|
52
|
+
unless current_caps.include?(capability)
|
|
53
|
+
return "'#{target}' does not have '#{capability}' in its declared capabilities."
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Remove the capability
|
|
57
|
+
target_po.config["capabilities"].delete(capability)
|
|
58
|
+
|
|
59
|
+
# Persist to file
|
|
60
|
+
saved = target_po.save
|
|
61
|
+
|
|
62
|
+
# Notify for real-time UI update
|
|
63
|
+
context.env.notify_po_modified(target_po)
|
|
64
|
+
|
|
65
|
+
if saved
|
|
66
|
+
"Removed '#{capability}' from '#{target}' and saved to file."
|
|
67
|
+
else
|
|
68
|
+
"Removed '#{capability}' from '#{target}' (in-memory only, could not save to file)."
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
data/lib/prompt_objects.rb
CHANGED
|
@@ -11,7 +11,7 @@ module PromptObjects
|
|
|
11
11
|
class Error < StandardError; end
|
|
12
12
|
|
|
13
13
|
# Universal capabilities available to all prompt objects (don't need to be declared)
|
|
14
|
-
UNIVERSAL_CAPABILITIES = %w[ask_human think create_capability add_capability list_capabilities list_primitives add_primitive create_primitive verify_primitive modify_primitive request_primitive].freeze
|
|
14
|
+
UNIVERSAL_CAPABILITIES = %w[ask_human think create_capability add_capability remove_capability list_capabilities list_primitives add_primitive create_primitive delete_primitive verify_primitive modify_primitive request_primitive modify_prompt].freeze
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
require_relative "prompt_objects/capability"
|
|
@@ -49,13 +49,16 @@ require_relative "prompt_objects/universal/ask_human"
|
|
|
49
49
|
require_relative "prompt_objects/universal/think"
|
|
50
50
|
require_relative "prompt_objects/universal/create_capability"
|
|
51
51
|
require_relative "prompt_objects/universal/add_capability"
|
|
52
|
+
require_relative "prompt_objects/universal/remove_capability"
|
|
52
53
|
require_relative "prompt_objects/universal/list_capabilities"
|
|
53
54
|
require_relative "prompt_objects/universal/list_primitives"
|
|
54
55
|
require_relative "prompt_objects/universal/add_primitive"
|
|
55
56
|
require_relative "prompt_objects/universal/create_primitive"
|
|
57
|
+
require_relative "prompt_objects/universal/delete_primitive"
|
|
56
58
|
require_relative "prompt_objects/universal/verify_primitive"
|
|
57
59
|
require_relative "prompt_objects/universal/modify_primitive"
|
|
58
60
|
require_relative "prompt_objects/universal/request_primitive"
|
|
61
|
+
require_relative "prompt_objects/universal/modify_prompt"
|
|
59
62
|
|
|
60
63
|
# Connectors (different interfaces to environments)
|
|
61
64
|
require_relative "prompt_objects/connectors/base"
|
data/prompt_objects.gemspec
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: prompt_objects
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Scott Werner
|
|
@@ -276,8 +276,8 @@ files:
|
|
|
276
276
|
- lib/prompt_objects/server/api/routes.rb
|
|
277
277
|
- lib/prompt_objects/server/app.rb
|
|
278
278
|
- lib/prompt_objects/server/file_watcher.rb
|
|
279
|
-
- lib/prompt_objects/server/public/assets/index-
|
|
280
|
-
- lib/prompt_objects/server/public/assets/index-
|
|
279
|
+
- lib/prompt_objects/server/public/assets/index-CeNJvqLG.js
|
|
280
|
+
- lib/prompt_objects/server/public/assets/index-Vx4-uMOU.css
|
|
281
281
|
- lib/prompt_objects/server/public/index.html
|
|
282
282
|
- lib/prompt_objects/server/websocket_handler.rb
|
|
283
283
|
- lib/prompt_objects/session/store.rb
|
|
@@ -286,9 +286,12 @@ files:
|
|
|
286
286
|
- lib/prompt_objects/universal/ask_human.rb
|
|
287
287
|
- lib/prompt_objects/universal/create_capability.rb
|
|
288
288
|
- lib/prompt_objects/universal/create_primitive.rb
|
|
289
|
+
- lib/prompt_objects/universal/delete_primitive.rb
|
|
289
290
|
- lib/prompt_objects/universal/list_capabilities.rb
|
|
290
291
|
- lib/prompt_objects/universal/list_primitives.rb
|
|
291
292
|
- lib/prompt_objects/universal/modify_primitive.rb
|
|
293
|
+
- lib/prompt_objects/universal/modify_prompt.rb
|
|
294
|
+
- lib/prompt_objects/universal/remove_capability.rb
|
|
292
295
|
- lib/prompt_objects/universal/request_primitive.rb
|
|
293
296
|
- lib/prompt_objects/universal/think.rb
|
|
294
297
|
- lib/prompt_objects/universal/verify_primitive.rb
|