mirror of
https://github.com/msoedov/agentic_security.git
synced 2026-06-24 06:09:55 +02:00
feat(add new spec samples):
This commit is contained in:
@@ -1,9 +1,17 @@
|
||||
import base64
|
||||
|
||||
import httpx
|
||||
from pydantic import BaseModel
|
||||
|
||||
|
||||
class InvalidHTTPSpecError(Exception):
|
||||
...
|
||||
def encode_image_base64_by_url(url: str = "https://github.com/fluidicon.png") -> str:
|
||||
"""Encode image data to base64 from a URL"""
|
||||
response = httpx.get(url)
|
||||
encoded_content = base64.b64encode(response.content).decode("utf-8")
|
||||
return "data:image/jpeg;base64," + encoded_content
|
||||
|
||||
|
||||
class InvalidHTTPSpecError(Exception): ...
|
||||
|
||||
|
||||
class LLMSpec(BaseModel):
|
||||
@@ -72,6 +80,15 @@ class LLMSpec(BaseModel):
|
||||
|
||||
return response
|
||||
|
||||
async def verify(self) -> httpx.Response:
|
||||
match self:
|
||||
case LLMSpec(has_image=True):
|
||||
return await self.probe("test", encode_image_base64_by_url())
|
||||
case LLMSpec(has_files=True):
|
||||
return await self._probe_with_files({})
|
||||
case _:
|
||||
return await self.probe("test prompt")
|
||||
|
||||
fn = probe
|
||||
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ router = APIRouter()
|
||||
@router.post("/verify")
|
||||
async def verify(info: LLMInfo):
|
||||
spec = LLMSpec.from_string(info.spec)
|
||||
r = await spec.probe("test")
|
||||
r = await spec.verify()
|
||||
if r.status_code >= 400:
|
||||
raise HTTPException(status_code=r.status_code, detail=r.text)
|
||||
return dict(
|
||||
|
||||
@@ -64,5 +64,36 @@ Content-Type: application/json
|
||||
{"role": "user", "content": "<<PROMPT>>"}
|
||||
]
|
||||
}
|
||||
`,
|
||||
`POST ${URL}/v1/self-probe-image
|
||||
Authorization: Bearer XXXXX
|
||||
Content-Type: application/json
|
||||
|
||||
[
|
||||
{
|
||||
"role": "user",
|
||||
"content": [
|
||||
{
|
||||
"type": "text",
|
||||
"text": "What is in this image?",
|
||||
},
|
||||
{
|
||||
"type": "image_url",
|
||||
"image_url": {
|
||||
"url": f"data:image/jpeg;base64,{<<BASE64_IMAGE>>}"
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
]
|
||||
`,
|
||||
`POST ${URL}/v1/self-probe-file
|
||||
Authorization: Bearer $GROQ_API_KEY
|
||||
Content-Type: multipart/form-data
|
||||
|
||||
{
|
||||
"file": "@./sample_audio.m4a",
|
||||
"model": "whisper-large-v3"
|
||||
}
|
||||
`,
|
||||
]
|
||||
|
||||
@@ -34,17 +34,23 @@
|
||||
[[% include "partials/concent.html" %]]
|
||||
|
||||
<main class="max-w-6xl mx-auto space-y-8">
|
||||
<!-- Config Selection -->
|
||||
<section class="bg-dark-card rounded-lg p-6 shadow-lg">
|
||||
<h2 class="text-2xl font-bold mb-4">Select a Config</h2>
|
||||
<div class="grid grid-cols-1 md:grid-cols-5 gap-4">
|
||||
<div v-for="(config, index) in configs" :key="index"
|
||||
|
||||
<div class="flex space-x-4 overflow-x-auto scrollbar-hide">
|
||||
<div
|
||||
v-for="(config, index) in configs"
|
||||
:key="index"
|
||||
@click="selectConfig(index)"
|
||||
class="border-2 rounded-lg p-4 flex flex-col items-start transition-all hover:shadow-md cursor-pointer"
|
||||
:class="{'border-dark-accent-green': selectedConfig === index, 'border-gray-600': selectedConfig !== index}">
|
||||
class="flex-none w-1/2 sm:w-1/3 md:w-1/4 lg:w-1/5 border-2 rounded-lg p-4 flex flex-col items-start transition-all hover:shadow-md cursor-pointer"
|
||||
:class="{
|
||||
'border-dark-accent-green': selectedConfig === index,
|
||||
'border-gray-600': selectedConfig !== index
|
||||
}">
|
||||
<div class="font-medium mb-2">{{ config.name }}</div>
|
||||
<div class="text-sm text-gray-400">{{config.customInstructions ||
|
||||
'Requires API key'}}</div>
|
||||
<div class="text-sm text-gray-400">
|
||||
{{ config.customInstructions || 'Requires API key' }}
|
||||
</div>
|
||||
<div class="mt-2 text-dark-accent-green font-semibold">API</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -35,6 +35,9 @@ var app = new Vue({
|
||||
{ name: 'Replicate', prompts: 40000 },
|
||||
{ name: 'Groq', prompts: 40000 },
|
||||
{ name: 'Together.ai', prompts: 40000 },
|
||||
{ name: 'Custom API Image', prompts: 40000, customInstructions: 'Requires api spec' },
|
||||
{ name: 'Custom API Files', prompts: 40000, customInstructions: 'Requires api spec' },
|
||||
|
||||
],
|
||||
dataConfig: [],
|
||||
},
|
||||
|
||||
@@ -38,4 +38,14 @@
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.scrollbar-hide::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
.scrollbar-hide {
|
||||
-ms-overflow-style: none; /* IE and Edge */
|
||||
scrollbar-width: none; /* Firefox */
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
|
||||
Reference in New Issue
Block a user