feat: creating list processor

This commit is contained in:
2025-10-05 15:02:12 +01:00
parent 64abf79f9c
commit 9948d2521b
8 changed files with 53 additions and 41 deletions

View File

@ -21,6 +21,8 @@ and add a good description for each one.
You can add fields if you think they make a lot of sense.
You can remove fields if they are not correct, but be sure before you do this.
You must respond in json format
`
const listJsonSchema = `
@ -79,7 +81,7 @@ type CreateListAgent struct {
stackModel models.StackModel
}
func (agent *CreateListAgent) CreateList(log *log.Logger, userID uuid.UUID, title string, userReq string) error {
func (agent *CreateListAgent) CreateList(log *log.Logger, userID uuid.UUID, stackID uuid.UUID, title string, userReq string) error {
request := client.AgentRequestBody{
Model: "policy/images",
Temperature: 0.3,
@ -107,6 +109,8 @@ func (agent *CreateListAgent) CreateList(log *log.Logger, userID uuid.UUID, titl
structuredOutput := resp.Choices[0].Message.Content
log.Info("", "res", structuredOutput)
var createListArgs createNewListArguments
err = json.Unmarshal([]byte(structuredOutput), &createListArgs)
if err != nil {
@ -116,6 +120,8 @@ func (agent *CreateListAgent) CreateList(log *log.Logger, userID uuid.UUID, titl
schemaItems := make([]model.SchemaItems, 0)
for _, field := range createListArgs.Fields {
schemaItems = append(schemaItems, model.SchemaItems{
StackID: stackID,
Item: field.Name,
Description: field.Description,
@ -123,11 +129,6 @@ func (agent *CreateListAgent) CreateList(log *log.Logger, userID uuid.UUID, titl
})
}
_, err = agent.stackModel.Save(ctx, userID, createListArgs.Title, createListArgs.Description, model.Progress_Complete)
if err != nil {
return fmt.Errorf("creating list agent, saving list: %w", err)
}
err = agent.stackModel.SaveItems(ctx, schemaItems)
if err != nil {
return fmt.Errorf("creating list agent, saving items: %w", err)

View File

@ -9,7 +9,7 @@ import (
const (
IMAGE_TYPE = "image"
STACK_TYPE = "list"
STACK_TYPE = "stack"
)
type ImageNotification struct {

View File

@ -46,7 +46,7 @@ func (p *StackProcessor) setStackToProcess(ctx context.Context, stack model.Stac
}
func (p *StackProcessor) extractInfo(ctx context.Context, stack model.Stacks) {
err := p.stackAgent.CreateList(p.logger, stack.UserID, stack.Name, stack.Description)
err := p.stackAgent.CreateList(p.logger, stack.UserID, stack.ID, stack.Name, stack.Description)
if err != nil {
// Again, wtf do we do?
// Although i think the agent actually returns an error when it's finished

View File

@ -41,7 +41,7 @@ func setupRouter(db *sql.DB, jwtManager *ourmiddleware.JwtManager) (chi.Router,
return nil, fmt.Errorf("processor: %w", err)
}
stackProcessorLog := createLogger("Stack0 Processor", os.Stdout)
stackProcessorLog := createLogger("Stack Processor", os.Stdout)
stackProcessor, err := processor.NewStackProcessor(stackProcessorLog, stackModel, &notifier)
if err != nil {
return nil, fmt.Errorf("processor: %w", err)
@ -50,7 +50,7 @@ func setupRouter(db *sql.DB, jwtManager *ourmiddleware.JwtManager) (chi.Router,
go imageProcessor.Processor.Work()
go stackProcessor.Processor.Work()
stackHandler := stacks.CreateStackHandler(db, limitsManager, jwtManager)
stackHandler := stacks.CreateStackHandler(db, limitsManager, jwtManager, stackProcessor.Processor)
authHandler := auth.CreateAuthHandler(db, jwtManager)
imageHandler := images.CreateImageHandler(db, limitsManager, jwtManager, imageProcessor.Processor)

View File

@ -8,6 +8,7 @@ import (
"screenmark/screenmark/limits"
"screenmark/screenmark/middleware"
"screenmark/screenmark/models"
"screenmark/screenmark/processor"
"github.com/charmbracelet/log"
"github.com/go-chi/chi/v5"
@ -23,6 +24,8 @@ type StackHandler struct {
limitsManager limits.LimitsManagerMethods
jwtManager *middleware.JwtManager
processor *processor.Processor[model.Stacks]
}
func (h *StackHandler) getAllStacks(w http.ResponseWriter, r *http.Request) {
@ -216,6 +219,8 @@ func (h *StackHandler) createStack(body CreateStackBody, w http.ResponseWriter,
return
}
h.processor.Add(stack)
middleware.WriteJsonOrError(h.logger, stack, w)
}
@ -237,7 +242,12 @@ func (h *StackHandler) CreateRoutes(r chi.Router) {
})
}
func CreateStackHandler(db *sql.DB, limitsManager limits.LimitsManagerMethods, jwtManager *middleware.JwtManager) StackHandler {
func CreateStackHandler(
db *sql.DB,
limitsManager limits.LimitsManagerMethods,
jwtManager *middleware.JwtManager,
processor *processor.Processor[model.Stacks],
) StackHandler {
stackModel := models.NewStackModel(db)
imageModel := models.NewImageModel(db)
logger := log.New(os.Stdout).WithPrefix("Stacks")
@ -248,5 +258,6 @@ func CreateStackHandler(db *sql.DB, limitsManager limits.LimitsManagerMethods, j
stackModel: stackModel,
limitsManager: limitsManager,
jwtManager: jwtManager,
processor: processor,
}
}

View File

@ -9,7 +9,7 @@ export const ProcessingImages: Component = () => {
const processingNumber = () =>
Object.keys(notifications.state.ProcessingImages).length +
Object.keys(notifications.state.ProcessingLists).length;
Object.keys(notifications.state.ProcessingStacks).length;
const [accessToken] = createResource(getAccessToken)
@ -60,13 +60,13 @@ export const ProcessingImages: Component = () => {
)}
</For>
<For each={Object.entries(notifications.state.ProcessingLists)}>
{([, _list]) => (
<Show when={_list}>
{(list) => (
<For each={Object.entries(notifications.state.ProcessingStacks)}>
{([, _stack]) => (
<Show when={_stack}>
{(stack) => (
<div class="flex gap-2 w-full justify-center">
<div class="flex flex-col gap-1">
<p class="text-slate-900">New Stack: {list().Name}</p>
<p class="text-slate-900">New Stack: {stack().Name}</p>
</div>
<LoadingCircle
status="loading"

View File

@ -22,7 +22,7 @@ type NotificationState = {
string,
InferOutput<typeof processingImagesValidator> | undefined
>;
ProcessingLists: Record<
ProcessingStacks: Record<
string,
InferOutput<typeof processingListValidator> | undefined
>;
@ -31,7 +31,7 @@ type NotificationState = {
export const Notifications = (onCompleteImage: () => void) => {
const [state, setState] = createStore<NotificationState>({
ProcessingImages: {},
ProcessingLists: {},
ProcessingStacks: {},
});
const { userImages } = useSearchImageContext();
@ -71,14 +71,14 @@ export const Notifications = (onCompleteImage: () => void) => {
} else {
setState("ProcessingImages", ImageID, notification.output);
}
} else if (notification.output.Type === "list") {
const { ListID, Status } = notification.output;
} else if (notification.output.Type === "stack") {
const { StackID, Status } = notification.output;
if (Status === "complete") {
setState("ProcessingLists", ListID, undefined);
setState("ProcessingStacks", StackID, undefined);
onCompleteImage();
} else {
setState("ProcessingLists", ListID, notification.output);
setState("ProcessingStacks", StackID, notification.output);
}
}
};

View File

@ -1,10 +1,10 @@
import { literal, pipe, strictObject, string, union, uuid } from "valibot";
export const processingListValidator = strictObject({
Type: literal("list"),
Type: literal("stack"),
Name: string(),
ListID: pipe(string(), uuid()),
StackID: pipe(string(), uuid()),
Status: union([
literal("not-started"),