chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,359 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
CREATE TABLE roles (
|
||||
id BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
name TEXT NOT NULL,
|
||||
|
||||
CONSTRAINT roles_name_unique UNIQUE (name)
|
||||
);
|
||||
|
||||
CREATE INDEX roles_name_idx ON roles(name);
|
||||
|
||||
INSERT INTO roles (name) VALUES
|
||||
('Admin'),
|
||||
('User')
|
||||
ON CONFLICT DO NOTHING;
|
||||
|
||||
CREATE TABLE privileges (
|
||||
id BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
role_id BIGINT NOT NULL REFERENCES roles(id),
|
||||
name TEXT NOT NULL,
|
||||
|
||||
CONSTRAINT privileges_role_name_unique UNIQUE (role_id, name)
|
||||
);
|
||||
|
||||
CREATE INDEX privileges_role_id_idx ON privileges(role_id);
|
||||
CREATE INDEX privileges_name_idx ON privileges(name);
|
||||
|
||||
INSERT INTO privileges (role_id, name) VALUES
|
||||
(1, 'users.create'),
|
||||
(1, 'users.delete'),
|
||||
(1, 'users.edit'),
|
||||
(1, 'users.view'),
|
||||
(1, 'roles.view'),
|
||||
(1, 'providers.view'),
|
||||
(1, 'prompts.view'),
|
||||
(1, 'prompts.edit'),
|
||||
(1, 'screenshots.admin'),
|
||||
(1, 'screenshots.view'),
|
||||
(1, 'screenshots.download'),
|
||||
(1, 'screenshots.subscribe'),
|
||||
(1, 'msglogs.admin'),
|
||||
(1, 'msglogs.view'),
|
||||
(1, 'msglogs.subscribe'),
|
||||
(1, 'termlogs.admin'),
|
||||
(1, 'termlogs.view'),
|
||||
(1, 'termlogs.subscribe'),
|
||||
(1, 'flows.admin'),
|
||||
(1, 'flows.create'),
|
||||
(1, 'flows.delete'),
|
||||
(1, 'flows.edit'),
|
||||
(1, 'flows.view'),
|
||||
(1, 'flows.subscribe'),
|
||||
(1, 'tasks.admin'),
|
||||
(1, 'tasks.view'),
|
||||
(1, 'tasks.subscribe'),
|
||||
(1, 'subtasks.admin'),
|
||||
(1, 'subtasks.view'),
|
||||
(1, 'containers.admin'),
|
||||
(1, 'containers.view')
|
||||
ON CONFLICT DO NOTHING;
|
||||
|
||||
CREATE TYPE USER_TYPE AS ENUM ('local','oauth');
|
||||
CREATE TYPE USER_STATUS AS ENUM ('created','active','blocked');
|
||||
|
||||
CREATE TABLE users (
|
||||
id BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
hash TEXT NOT NULL DEFAULT MD5(RANDOM()::text),
|
||||
type USER_TYPE NOT NULL DEFAULT 'local',
|
||||
mail TEXT NOT NULL,
|
||||
name TEXT NOT NULL DEFAULT '',
|
||||
password TEXT DEFAULT NULL,
|
||||
status USER_STATUS NOT NULL DEFAULT 'created',
|
||||
role_id BIGINT NOT NULL DEFAULT '2' REFERENCES roles(id),
|
||||
password_change_required BOOLEAN NOT NULL DEFAULT false,
|
||||
provider TEXT NULL,
|
||||
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT users_mail_unique UNIQUE (mail),
|
||||
CONSTRAINT users_hash_unique UNIQUE (hash)
|
||||
);
|
||||
|
||||
CREATE INDEX users_role_id_idx ON users(role_id);
|
||||
CREATE INDEX users_hash_idx ON users(hash);
|
||||
|
||||
INSERT INTO users (mail, name, password, status, role_id, password_change_required) VALUES
|
||||
(
|
||||
'admin@pentagi.com',
|
||||
'admin',
|
||||
'$2a$10$deVOk0o1nYRHpaVXjIcyCuRmaHvtoMN/2RUT7w5XbZTeiWKEbXx9q',
|
||||
'active',
|
||||
1,
|
||||
true
|
||||
)
|
||||
ON CONFLICT DO NOTHING;
|
||||
|
||||
CREATE TABLE prompts (
|
||||
id BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
type TEXT NOT NULL,
|
||||
user_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
prompt TEXT NOT NULL,
|
||||
|
||||
CONSTRAINT prompts_type_user_id_unique UNIQUE (type, user_id)
|
||||
);
|
||||
|
||||
CREATE INDEX prompts_type_idx ON prompts(type);
|
||||
CREATE INDEX prompts_user_id_idx ON prompts(user_id);
|
||||
CREATE INDEX prompts_prompt_idx ON prompts(prompt);
|
||||
|
||||
CREATE TYPE FLOW_STATUS AS ENUM ('created','running','waiting','finished','failed');
|
||||
|
||||
CREATE TABLE flows (
|
||||
id BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
status FLOW_STATUS NOT NULL DEFAULT 'created',
|
||||
title TEXT NOT NULL DEFAULT 'untitled',
|
||||
model TEXT NOT NULL,
|
||||
model_provider TEXT NOT NULL,
|
||||
language TEXT NOT NULL,
|
||||
functions JSON NOT NULL DEFAULT '{}',
|
||||
prompts JSON NOT NULL,
|
||||
user_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
||||
deleted_at TIMESTAMPTZ NULL
|
||||
);
|
||||
|
||||
CREATE INDEX flows_status_idx ON flows(status);
|
||||
CREATE INDEX flows_title_idx ON flows(title);
|
||||
CREATE INDEX flows_language_idx ON flows(language);
|
||||
CREATE INDEX flows_model_provider_idx ON flows(model_provider);
|
||||
CREATE INDEX flows_user_id_idx ON flows(user_id);
|
||||
|
||||
CREATE TYPE CONTAINER_TYPE AS ENUM ('primary','secondary');
|
||||
CREATE TYPE CONTAINER_STATUS AS ENUM ('starting','running','stopped','deleted','failed');
|
||||
|
||||
CREATE TABLE containers (
|
||||
id BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
type CONTAINER_TYPE NOT NULL DEFAULT 'primary',
|
||||
name TEXT NOT NULL DEFAULT MD5(RANDOM()::text),
|
||||
image TEXT NOT NULL,
|
||||
status CONTAINER_STATUS NOT NULL DEFAULT 'starting',
|
||||
local_id TEXT,
|
||||
local_dir TEXT,
|
||||
flow_id BIGINT NOT NULL REFERENCES flows(id) ON DELETE CASCADE,
|
||||
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT containers_local_id_unique UNIQUE (local_id)
|
||||
);
|
||||
|
||||
CREATE INDEX containers_type_idx ON containers(type);
|
||||
CREATE INDEX containers_name_idx ON containers(name);
|
||||
CREATE INDEX containers_status_idx ON containers(status);
|
||||
CREATE INDEX containers_flow_id_idx ON containers(flow_id);
|
||||
|
||||
CREATE TYPE TASK_STATUS AS ENUM ('created','running','waiting','finished','failed');
|
||||
|
||||
CREATE TABLE tasks (
|
||||
id BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
status TASK_STATUS NOT NULL DEFAULT 'created',
|
||||
title TEXT NOT NULL DEFAULT 'untitled',
|
||||
input TEXT NOT NULL,
|
||||
result TEXT NOT NULL DEFAULT '',
|
||||
flow_id BIGINT NOT NULL REFERENCES flows(id) ON DELETE CASCADE,
|
||||
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE INDEX tasks_status_idx ON tasks(status);
|
||||
CREATE INDEX tasks_title_idx ON tasks(title);
|
||||
CREATE INDEX tasks_input_idx ON tasks(input);
|
||||
CREATE INDEX tasks_result_idx ON tasks(result);
|
||||
CREATE INDEX tasks_flow_id_idx ON tasks(flow_id);
|
||||
|
||||
CREATE TYPE SUBTASK_STATUS AS ENUM ('created','running','waiting','finished','failed');
|
||||
|
||||
CREATE TABLE subtasks (
|
||||
id BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
status SUBTASK_STATUS NOT NULL DEFAULT 'created',
|
||||
title TEXT NOT NULL,
|
||||
description TEXT NOT NULL,
|
||||
result TEXT NOT NULL DEFAULT '',
|
||||
task_id BIGINT NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,
|
||||
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE INDEX subtasks_status_idx ON subtasks(status);
|
||||
CREATE INDEX subtasks_title_idx ON subtasks(title);
|
||||
CREATE INDEX subtasks_description_idx ON subtasks(description);
|
||||
CREATE INDEX subtasks_result_idx ON subtasks(result);
|
||||
CREATE INDEX subtasks_task_id_idx ON subtasks(task_id);
|
||||
|
||||
CREATE TYPE TOOLCALL_STATUS AS ENUM ('received','running','finished','failed');
|
||||
|
||||
CREATE TABLE toolcalls (
|
||||
id BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
call_id TEXT NOT NULL,
|
||||
status TOOLCALL_STATUS NOT NULL DEFAULT 'received',
|
||||
name TEXT NOT NULL,
|
||||
args JSON NOT NULL,
|
||||
result TEXT NOT NULL DEFAULT '',
|
||||
flow_id BIGINT NOT NULL REFERENCES flows(id) ON DELETE CASCADE,
|
||||
task_id BIGINT NULL REFERENCES tasks(id) ON DELETE CASCADE,
|
||||
subtask_id BIGINT NULL REFERENCES subtasks(id) ON DELETE CASCADE,
|
||||
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE INDEX toolcalls_call_id_idx ON toolcalls(call_id);
|
||||
CREATE INDEX toolcalls_status_idx ON toolcalls(status);
|
||||
CREATE INDEX toolcalls_name_idx ON toolcalls(name);
|
||||
CREATE INDEX toolcalls_flow_id_idx ON toolcalls(flow_id);
|
||||
CREATE INDEX toolcalls_task_id_idx ON toolcalls(task_id);
|
||||
CREATE INDEX toolcalls_subtask_id_idx ON toolcalls(subtask_id);
|
||||
|
||||
CREATE TYPE MSGCHAIN_TYPE AS ENUM (
|
||||
'primary_agent',
|
||||
'reporter',
|
||||
'generator',
|
||||
'refiner',
|
||||
'reflector',
|
||||
'enricher',
|
||||
'adviser',
|
||||
'coder',
|
||||
'memorist',
|
||||
'searcher',
|
||||
'installer',
|
||||
'pentester',
|
||||
'summarizer'
|
||||
);
|
||||
|
||||
CREATE TABLE msgchains (
|
||||
id BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
type MSGCHAIN_TYPE NOT NULL DEFAULT 'primary_agent',
|
||||
model TEXT NOT NULL,
|
||||
model_provider TEXT NOT NULL,
|
||||
usage_in BIGINT NOT NULL DEFAULT 0,
|
||||
usage_out BIGINT NOT NULL DEFAULT 0,
|
||||
chain JSON NOT NULL,
|
||||
flow_id BIGINT NOT NULL REFERENCES flows(id) ON DELETE CASCADE,
|
||||
task_id BIGINT NULL REFERENCES tasks(id) ON DELETE CASCADE,
|
||||
subtask_id BIGINT NULL REFERENCES subtasks(id) ON DELETE CASCADE,
|
||||
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE INDEX msgchains_type_idx ON msgchains(type);
|
||||
CREATE INDEX msgchains_flow_id_idx ON msgchains(flow_id);
|
||||
CREATE INDEX msgchains_task_id_idx ON msgchains(task_id);
|
||||
CREATE INDEX msgchains_subtask_id_idx ON msgchains(subtask_id);
|
||||
|
||||
CREATE TYPE TERMLOG_TYPE AS ENUM ('stdin', 'stdout','stderr');
|
||||
|
||||
CREATE TABLE termlogs (
|
||||
id BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
type TERMLOG_TYPE NOT NULL,
|
||||
text TEXT NOT NULL,
|
||||
container_id BIGINT NOT NULL REFERENCES containers(id) ON DELETE CASCADE,
|
||||
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE INDEX termlogs_type_idx ON termlogs(type);
|
||||
-- CREATE INDEX termlogs_text_idx ON termlogs(text);
|
||||
CREATE INDEX termlogs_container_id_idx ON termlogs(container_id);
|
||||
|
||||
CREATE TYPE MSGLOG_TYPE AS ENUM ('thoughts', 'browser', 'terminal', 'file', 'search', 'advice', 'ask', 'input', 'done');
|
||||
|
||||
CREATE TABLE msglogs (
|
||||
id BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
type MSGLOG_TYPE NOT NULL,
|
||||
message TEXT NOT NULL,
|
||||
result TEXT NOT NULL DEFAULT '',
|
||||
flow_id BIGINT NOT NULL REFERENCES flows(id) ON DELETE CASCADE,
|
||||
task_id BIGINT NULL REFERENCES tasks(id) ON DELETE CASCADE,
|
||||
subtask_id BIGINT NULL REFERENCES subtasks(id) ON DELETE CASCADE,
|
||||
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE INDEX msglogs_type_idx ON msglogs(type);
|
||||
CREATE INDEX msglogs_message_idx ON msglogs(message);
|
||||
CREATE INDEX msglogs_flow_id_idx ON msglogs(flow_id);
|
||||
CREATE INDEX msglogs_task_id_idx ON msglogs(task_id);
|
||||
CREATE INDEX msglogs_subtask_id_idx ON msglogs(subtask_id);
|
||||
|
||||
CREATE TABLE screenshots (
|
||||
id BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
name TEXT NOT NULL,
|
||||
url TEXT NOT NULL,
|
||||
flow_id BIGINT NOT NULL REFERENCES flows(id) ON DELETE CASCADE,
|
||||
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE INDEX screenshots_flow_id_idx ON screenshots(flow_id);
|
||||
CREATE INDEX screenshots_name_idx ON screenshots(name);
|
||||
CREATE INDEX screenshots_url_idx ON screenshots(url);
|
||||
|
||||
CREATE OR REPLACE FUNCTION update_modified_column()
|
||||
RETURNS TRIGGER AS
|
||||
$$
|
||||
BEGIN
|
||||
NEW.updated_at = now();
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$
|
||||
LANGUAGE plpgsql;
|
||||
|
||||
CREATE OR REPLACE TRIGGER update_flows_modified
|
||||
BEFORE UPDATE ON flows
|
||||
FOR EACH ROW EXECUTE PROCEDURE update_modified_column();
|
||||
|
||||
CREATE OR REPLACE TRIGGER update_tasks_modified
|
||||
BEFORE UPDATE ON tasks
|
||||
FOR EACH ROW EXECUTE PROCEDURE update_modified_column();
|
||||
|
||||
CREATE OR REPLACE TRIGGER update_subtasks_modified
|
||||
BEFORE UPDATE ON subtasks
|
||||
FOR EACH ROW EXECUTE PROCEDURE update_modified_column();
|
||||
|
||||
CREATE OR REPLACE TRIGGER update_containers_modified
|
||||
BEFORE UPDATE ON containers
|
||||
FOR EACH ROW EXECUTE PROCEDURE update_modified_column();
|
||||
|
||||
CREATE OR REPLACE TRIGGER update_toolcalls_modified
|
||||
BEFORE UPDATE ON toolcalls
|
||||
FOR EACH ROW EXECUTE PROCEDURE update_modified_column();
|
||||
|
||||
CREATE OR REPLACE TRIGGER update_msgchains_modified
|
||||
BEFORE UPDATE ON msgchains
|
||||
FOR EACH ROW EXECUTE PROCEDURE update_modified_column();
|
||||
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
DROP TABLE screenshots;
|
||||
DROP TABLE msglogs;
|
||||
DROP TABLE termlogs;
|
||||
DROP TABLE msgchains;
|
||||
DROP TABLE toolcalls;
|
||||
DROP TABLE subtasks;
|
||||
DROP TABLE tasks;
|
||||
DROP TABLE containers;
|
||||
DROP TABLE flows;
|
||||
DROP TABLE users;
|
||||
DROP TABLE roles;
|
||||
DROP TABLE privileges;
|
||||
DROP TYPE MSGLOG_TYPE;
|
||||
DROP TYPE TERMLOG_TYPE;
|
||||
DROP TYPE MSGCHAIN_TYPE;
|
||||
DROP TYPE TOOLCALL_STATUS;
|
||||
DROP TYPE SUBTASK_STATUS;
|
||||
DROP TYPE TASK_STATUS;
|
||||
DROP TYPE CONTAINER_STATUS;
|
||||
DROP TYPE CONTAINER_TYPE;
|
||||
DROP TYPE FLOW_STATUS;
|
||||
DROP TYPE USER_STATUS;
|
||||
DROP TYPE USER_TYPE;
|
||||
DROP FUNCTION update_modified_column;
|
||||
-- +goose StatementEnd
|
||||
@@ -0,0 +1,101 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
INSERT INTO privileges (role_id, name) VALUES
|
||||
(1, 'agentlogs.admin'),
|
||||
(1, 'agentlogs.view'),
|
||||
(1, 'agentlogs.subscribe'),
|
||||
(1, 'vecstorelogs.admin'),
|
||||
(1, 'vecstorelogs.view'),
|
||||
(1, 'vecstorelogs.subscribe'),
|
||||
(1, 'searchlogs.admin'),
|
||||
(1, 'searchlogs.view'),
|
||||
(1, 'searchlogs.subscribe')
|
||||
ON CONFLICT DO NOTHING;
|
||||
|
||||
CREATE TABLE agentlogs (
|
||||
id BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
initiator MSGCHAIN_TYPE NOT NULL DEFAULT 'primary_agent',
|
||||
executor MSGCHAIN_TYPE NOT NULL DEFAULT 'primary_agent',
|
||||
task TEXT NOT NULL,
|
||||
result TEXT NOT NULL DEFAULT '',
|
||||
flow_id BIGINT NOT NULL REFERENCES flows(id) ON DELETE CASCADE,
|
||||
task_id BIGINT NULL REFERENCES tasks(id) ON DELETE CASCADE,
|
||||
subtask_id BIGINT NULL REFERENCES subtasks(id) ON DELETE CASCADE,
|
||||
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE INDEX agentlogs_initiator_idx ON agentlogs(initiator);
|
||||
CREATE INDEX agentlogs_executor_idx ON agentlogs(executor);
|
||||
CREATE INDEX agentlogs_task_idx ON agentlogs(task);
|
||||
CREATE INDEX agentlogs_flow_id_idx ON agentlogs(flow_id);
|
||||
CREATE INDEX agentlogs_task_id_idx ON agentlogs(task_id);
|
||||
CREATE INDEX agentlogs_subtask_id_idx ON agentlogs(subtask_id);
|
||||
|
||||
CREATE TYPE VECSTORE_ACTION_TYPE AS ENUM ('retrieve', 'store');
|
||||
|
||||
CREATE TABLE vecstorelogs (
|
||||
id BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
initiator MSGCHAIN_TYPE NOT NULL DEFAULT 'primary_agent',
|
||||
executor MSGCHAIN_TYPE NOT NULL DEFAULT 'primary_agent',
|
||||
filter JSON NOT NULL DEFAULT '{}',
|
||||
query TEXT NOT NULL,
|
||||
action VECSTORE_ACTION_TYPE NOT NULL,
|
||||
result TEXT NOT NULL,
|
||||
flow_id BIGINT NOT NULL REFERENCES flows(id) ON DELETE CASCADE,
|
||||
task_id BIGINT NULL REFERENCES tasks(id) ON DELETE CASCADE,
|
||||
subtask_id BIGINT NULL REFERENCES subtasks(id) ON DELETE CASCADE,
|
||||
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE INDEX vecstorelogs_initiator_idx ON vecstorelogs(initiator);
|
||||
CREATE INDEX vecstorelogs_executor_idx ON vecstorelogs(executor);
|
||||
CREATE INDEX vecstorelogs_query_idx ON vecstorelogs(query);
|
||||
CREATE INDEX vecstorelogs_action_idx ON vecstorelogs(action);
|
||||
CREATE INDEX vecstorelogs_flow_id_idx ON vecstorelogs(flow_id);
|
||||
CREATE INDEX vecstorelogs_task_id_idx ON vecstorelogs(task_id);
|
||||
CREATE INDEX vecstorelogs_subtask_id_idx ON vecstorelogs(subtask_id);
|
||||
|
||||
CREATE TYPE SEARCHENGINE_TYPE AS ENUM ('google', 'tavily', 'traversaal', 'browser');
|
||||
|
||||
CREATE TABLE searchlogs (
|
||||
id BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
initiator MSGCHAIN_TYPE NOT NULL DEFAULT 'primary_agent',
|
||||
executor MSGCHAIN_TYPE NOT NULL DEFAULT 'primary_agent',
|
||||
engine SEARCHENGINE_TYPE NOT NULL,
|
||||
query TEXT NOT NULL,
|
||||
result TEXT NOT NULL DEFAULT '',
|
||||
flow_id BIGINT NOT NULL REFERENCES flows(id) ON DELETE CASCADE,
|
||||
task_id BIGINT NULL REFERENCES tasks(id) ON DELETE CASCADE,
|
||||
subtask_id BIGINT NULL REFERENCES subtasks(id) ON DELETE CASCADE,
|
||||
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE INDEX searchlogs_initiator_idx ON searchlogs(initiator);
|
||||
CREATE INDEX searchlogs_executor_idx ON searchlogs(executor);
|
||||
CREATE INDEX searchlogs_engine_idx ON searchlogs(engine);
|
||||
CREATE INDEX searchlogs_query_idx ON searchlogs(query);
|
||||
CREATE INDEX searchlogs_flow_id_idx ON searchlogs(flow_id);
|
||||
CREATE INDEX searchlogs_task_id_idx ON searchlogs(task_id);
|
||||
CREATE INDEX searchlogs_subtask_id_idx ON searchlogs(subtask_id);
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
DROP TABLE agentlogs;
|
||||
DROP TABLE vecstorelogs;
|
||||
DROP TABLE searchlogs;
|
||||
DROP TYPE VECSTORE_ACTION_TYPE;
|
||||
DROP TYPE SEARCHENGINE_TYPE;
|
||||
|
||||
DELETE FROM privileges WHERE name IN (
|
||||
'agentlogs.admin',
|
||||
'agentlogs.view',
|
||||
'agentlogs.subscribe',
|
||||
'vecstorelogs.admin',
|
||||
'vecstorelogs.view',
|
||||
'vecstorelogs.subscribe',
|
||||
'searchlogs.admin',
|
||||
'searchlogs.view',
|
||||
'searchlogs.subscribe'
|
||||
);
|
||||
-- +goose StatementEnd
|
||||
@@ -0,0 +1,35 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
INSERT INTO privileges (role_id, name) VALUES
|
||||
(2, 'roles.view'),
|
||||
(2, 'providers.view'),
|
||||
(2, 'prompts.view'),
|
||||
(2, 'screenshots.view'),
|
||||
(2, 'screenshots.download'),
|
||||
(2, 'screenshots.subscribe'),
|
||||
(2, 'msglogs.view'),
|
||||
(2, 'msglogs.subscribe'),
|
||||
(2, 'termlogs.view'),
|
||||
(2, 'termlogs.subscribe'),
|
||||
(2, 'flows.create'),
|
||||
(2, 'flows.delete'),
|
||||
(2, 'flows.edit'),
|
||||
(2, 'flows.view'),
|
||||
(2, 'flows.subscribe'),
|
||||
(2, 'tasks.view'),
|
||||
(2, 'tasks.subscribe'),
|
||||
(2, 'subtasks.view'),
|
||||
(2, 'containers.view'),
|
||||
(2, 'agentlogs.view'),
|
||||
(2, 'agentlogs.subscribe'),
|
||||
(2, 'vecstorelogs.view'),
|
||||
(2, 'vecstorelogs.subscribe'),
|
||||
(2, 'searchlogs.view'),
|
||||
(2, 'searchlogs.subscribe')
|
||||
ON CONFLICT DO NOTHING;
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
DELETE FROM privileges WHERE role_id = 2;
|
||||
-- +goose StatementEnd
|
||||
@@ -0,0 +1,19 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
CREATE TYPE MSGLOG_RESULT_FORMAT AS ENUM ('plain', 'markdown', 'terminal');
|
||||
|
||||
ALTER TABLE msglogs ADD COLUMN result_format MSGLOG_RESULT_FORMAT NULL DEFAULT 'plain';
|
||||
|
||||
UPDATE msglogs SET result_format = 'plain';
|
||||
|
||||
ALTER TABLE msglogs ALTER COLUMN result_format SET NOT NULL;
|
||||
|
||||
CREATE INDEX msglogs_result_format_idx ON msglogs(result_format);
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
ALTER TABLE msglogs DROP COLUMN result_format;
|
||||
|
||||
DROP TYPE MSGLOG_RESULT_FORMAT;
|
||||
-- +goose StatementEnd
|
||||
@@ -0,0 +1,11 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
ALTER TABLE flows ADD COLUMN trace_id TEXT NULL;
|
||||
|
||||
CREATE INDEX flows_trace_id_idx ON flows(trace_id);
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
ALTER TABLE flows DROP COLUMN trace_id;
|
||||
-- +goose StatementEnd
|
||||
@@ -0,0 +1,138 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
ALTER TABLE msgchains ALTER COLUMN type DROP DEFAULT;
|
||||
ALTER TABLE agentlogs ALTER COLUMN initiator DROP DEFAULT;
|
||||
ALTER TABLE agentlogs ALTER COLUMN executor DROP DEFAULT;
|
||||
ALTER TABLE vecstorelogs ALTER COLUMN initiator DROP DEFAULT;
|
||||
ALTER TABLE vecstorelogs ALTER COLUMN executor DROP DEFAULT;
|
||||
ALTER TABLE searchlogs ALTER COLUMN initiator DROP DEFAULT;
|
||||
ALTER TABLE searchlogs ALTER COLUMN executor DROP DEFAULT;
|
||||
|
||||
CREATE TYPE MSGCHAIN_TYPE_NEW AS ENUM (
|
||||
'primary_agent',
|
||||
'reporter',
|
||||
'generator',
|
||||
'refiner',
|
||||
'reflector',
|
||||
'enricher',
|
||||
'adviser',
|
||||
'coder',
|
||||
'memorist',
|
||||
'searcher',
|
||||
'installer',
|
||||
'pentester',
|
||||
'summarizer',
|
||||
'tool_call_fixer'
|
||||
);
|
||||
|
||||
ALTER TABLE msgchains
|
||||
ALTER COLUMN type TYPE MSGCHAIN_TYPE_NEW USING type::text::MSGCHAIN_TYPE_NEW;
|
||||
|
||||
ALTER TABLE agentlogs
|
||||
ALTER COLUMN initiator TYPE MSGCHAIN_TYPE_NEW USING initiator::text::MSGCHAIN_TYPE_NEW,
|
||||
ALTER COLUMN executor TYPE MSGCHAIN_TYPE_NEW USING executor::text::MSGCHAIN_TYPE_NEW;
|
||||
|
||||
ALTER TABLE vecstorelogs
|
||||
ALTER COLUMN initiator TYPE MSGCHAIN_TYPE_NEW USING initiator::text::MSGCHAIN_TYPE_NEW,
|
||||
ALTER COLUMN executor TYPE MSGCHAIN_TYPE_NEW USING executor::text::MSGCHAIN_TYPE_NEW;
|
||||
|
||||
ALTER TABLE searchlogs
|
||||
ALTER COLUMN initiator TYPE MSGCHAIN_TYPE_NEW USING initiator::text::MSGCHAIN_TYPE_NEW,
|
||||
ALTER COLUMN executor TYPE MSGCHAIN_TYPE_NEW USING executor::text::MSGCHAIN_TYPE_NEW;
|
||||
|
||||
DROP TYPE MSGCHAIN_TYPE;
|
||||
|
||||
ALTER TYPE MSGCHAIN_TYPE_NEW RENAME TO MSGCHAIN_TYPE;
|
||||
|
||||
ALTER TABLE msgchains
|
||||
ALTER COLUMN type SET NOT NULL,
|
||||
ALTER COLUMN type SET DEFAULT 'primary_agent';
|
||||
|
||||
ALTER TABLE agentlogs
|
||||
ALTER COLUMN initiator SET NOT NULL,
|
||||
ALTER COLUMN initiator SET DEFAULT 'primary_agent',
|
||||
ALTER COLUMN executor SET NOT NULL,
|
||||
ALTER COLUMN executor SET DEFAULT 'primary_agent';
|
||||
|
||||
ALTER TABLE vecstorelogs
|
||||
ALTER COLUMN initiator SET NOT NULL,
|
||||
ALTER COLUMN initiator SET DEFAULT 'primary_agent',
|
||||
ALTER COLUMN executor SET NOT NULL,
|
||||
ALTER COLUMN executor SET DEFAULT 'primary_agent';
|
||||
|
||||
ALTER TABLE searchlogs
|
||||
ALTER COLUMN initiator SET NOT NULL,
|
||||
ALTER COLUMN initiator SET DEFAULT 'primary_agent',
|
||||
ALTER COLUMN executor SET NOT NULL,
|
||||
ALTER COLUMN executor SET DEFAULT 'primary_agent';
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
DELETE FROM msgchains WHERE type = 'tool_call_fixer';
|
||||
|
||||
ALTER TABLE msgchains ALTER COLUMN type DROP DEFAULT;
|
||||
ALTER TABLE agentlogs ALTER COLUMN initiator DROP DEFAULT;
|
||||
ALTER TABLE agentlogs ALTER COLUMN executor DROP DEFAULT;
|
||||
ALTER TABLE vecstorelogs ALTER COLUMN initiator DROP DEFAULT;
|
||||
ALTER TABLE vecstorelogs ALTER COLUMN executor DROP DEFAULT;
|
||||
ALTER TABLE searchlogs ALTER COLUMN initiator DROP DEFAULT;
|
||||
ALTER TABLE searchlogs ALTER COLUMN executor DROP DEFAULT;
|
||||
|
||||
CREATE TYPE MSGCHAIN_TYPE_NEW AS ENUM (
|
||||
'primary_agent',
|
||||
'reporter',
|
||||
'generator',
|
||||
'refiner',
|
||||
'reflector',
|
||||
'enricher',
|
||||
'adviser',
|
||||
'coder',
|
||||
'memorist',
|
||||
'searcher',
|
||||
'installer',
|
||||
'pentester',
|
||||
'summarizer'
|
||||
);
|
||||
|
||||
ALTER TABLE msgchains
|
||||
ALTER COLUMN type TYPE MSGCHAIN_TYPE_NEW USING type::text::MSGCHAIN_TYPE_NEW;
|
||||
|
||||
ALTER TABLE agentlogs
|
||||
ALTER COLUMN initiator TYPE MSGCHAIN_TYPE_NEW USING initiator::text::MSGCHAIN_TYPE_NEW,
|
||||
ALTER COLUMN executor TYPE MSGCHAIN_TYPE_NEW USING executor::text::MSGCHAIN_TYPE_NEW;
|
||||
|
||||
ALTER TABLE vecstorelogs
|
||||
ALTER COLUMN initiator TYPE MSGCHAIN_TYPE_NEW USING initiator::text::MSGCHAIN_TYPE_NEW,
|
||||
ALTER COLUMN executor TYPE MSGCHAIN_TYPE_NEW USING executor::text::MSGCHAIN_TYPE_NEW;
|
||||
|
||||
ALTER TABLE searchlogs
|
||||
ALTER COLUMN initiator TYPE MSGCHAIN_TYPE_NEW USING initiator::text::MSGCHAIN_TYPE_NEW,
|
||||
ALTER COLUMN executor TYPE MSGCHAIN_TYPE_NEW USING executor::text::MSGCHAIN_TYPE_NEW;
|
||||
|
||||
DROP TYPE MSGCHAIN_TYPE;
|
||||
|
||||
ALTER TYPE MSGCHAIN_TYPE_NEW RENAME TO MSGCHAIN_TYPE;
|
||||
|
||||
ALTER TABLE msgchains
|
||||
ALTER COLUMN type SET NOT NULL,
|
||||
ALTER COLUMN type SET DEFAULT 'primary_agent';
|
||||
|
||||
ALTER TABLE agentlogs
|
||||
ALTER COLUMN initiator SET NOT NULL,
|
||||
ALTER COLUMN initiator SET DEFAULT 'primary_agent',
|
||||
ALTER COLUMN executor SET NOT NULL,
|
||||
ALTER COLUMN executor SET DEFAULT 'primary_agent';
|
||||
|
||||
ALTER TABLE vecstorelogs
|
||||
ALTER COLUMN initiator SET NOT NULL,
|
||||
ALTER COLUMN initiator SET DEFAULT 'primary_agent',
|
||||
ALTER COLUMN executor SET NOT NULL,
|
||||
ALTER COLUMN executor SET DEFAULT 'primary_agent';
|
||||
|
||||
ALTER TABLE searchlogs
|
||||
ALTER COLUMN initiator SET NOT NULL,
|
||||
ALTER COLUMN initiator SET DEFAULT 'primary_agent',
|
||||
ALTER COLUMN executor SET NOT NULL,
|
||||
ALTER COLUMN executor SET DEFAULT 'primary_agent';
|
||||
-- +goose StatementEnd
|
||||
@@ -0,0 +1,50 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
ALTER TABLE searchlogs ALTER COLUMN engine DROP DEFAULT;
|
||||
|
||||
CREATE TYPE SEARCHENGINE_TYPE_NEW AS ENUM (
|
||||
'google',
|
||||
'tavily',
|
||||
'traversaal',
|
||||
'browser',
|
||||
'duckduckgo',
|
||||
'perplexity'
|
||||
);
|
||||
|
||||
ALTER TABLE searchlogs
|
||||
ALTER COLUMN engine TYPE SEARCHENGINE_TYPE_NEW USING engine::text::SEARCHENGINE_TYPE_NEW;
|
||||
|
||||
DROP TYPE SEARCHENGINE_TYPE;
|
||||
|
||||
ALTER TYPE SEARCHENGINE_TYPE_NEW RENAME TO SEARCHENGINE_TYPE;
|
||||
|
||||
ALTER TABLE searchlogs
|
||||
ALTER COLUMN engine SET NOT NULL;
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
ALTER TABLE searchlogs ALTER COLUMN engine DROP DEFAULT;
|
||||
|
||||
CREATE TYPE SEARCHENGINE_TYPE_NEW AS ENUM (
|
||||
'google',
|
||||
'tavily',
|
||||
'traversaal',
|
||||
'browser'
|
||||
);
|
||||
|
||||
ALTER TABLE searchlogs
|
||||
ALTER COLUMN engine TYPE SEARCHENGINE_TYPE_NEW USING
|
||||
CASE
|
||||
WHEN engine::text = 'duckduckgo' THEN 'google'::text
|
||||
WHEN engine::text = 'perplexity' THEN 'browser'::text
|
||||
ELSE engine::text
|
||||
END::SEARCHENGINE_TYPE_NEW;
|
||||
|
||||
DROP TYPE SEARCHENGINE_TYPE;
|
||||
|
||||
ALTER TYPE SEARCHENGINE_TYPE_NEW RENAME TO SEARCHENGINE_TYPE;
|
||||
|
||||
ALTER TABLE searchlogs
|
||||
ALTER COLUMN engine SET NOT NULL;
|
||||
-- +goose StatementEnd
|
||||
@@ -0,0 +1,298 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
INSERT INTO privileges (role_id, name) VALUES
|
||||
(1, 'assistants.admin'),
|
||||
(1, 'assistants.create'),
|
||||
(1, 'assistants.delete'),
|
||||
(1, 'assistants.edit'),
|
||||
(1, 'assistants.view'),
|
||||
(1, 'assistants.subscribe'),
|
||||
(1, 'assistantlogs.admin'),
|
||||
(1, 'assistantlogs.view'),
|
||||
(1, 'assistantlogs.subscribe'),
|
||||
(2, 'assistants.create'),
|
||||
(2, 'assistants.delete'),
|
||||
(2, 'assistants.edit'),
|
||||
(2, 'assistants.view'),
|
||||
(2, 'assistants.subscribe'),
|
||||
(2, 'assistantlogs.view'),
|
||||
(2, 'assistantlogs.subscribe');
|
||||
|
||||
ALTER TABLE msgchains ALTER COLUMN type DROP DEFAULT;
|
||||
ALTER TABLE agentlogs ALTER COLUMN initiator DROP DEFAULT;
|
||||
ALTER TABLE agentlogs ALTER COLUMN executor DROP DEFAULT;
|
||||
ALTER TABLE vecstorelogs ALTER COLUMN initiator DROP DEFAULT;
|
||||
ALTER TABLE vecstorelogs ALTER COLUMN executor DROP DEFAULT;
|
||||
ALTER TABLE searchlogs ALTER COLUMN initiator DROP DEFAULT;
|
||||
ALTER TABLE searchlogs ALTER COLUMN executor DROP DEFAULT;
|
||||
|
||||
CREATE TYPE MSGCHAIN_TYPE_NEW AS ENUM (
|
||||
'primary_agent',
|
||||
'reporter',
|
||||
'generator',
|
||||
'refiner',
|
||||
'reflector',
|
||||
'enricher',
|
||||
'adviser',
|
||||
'coder',
|
||||
'memorist',
|
||||
'searcher',
|
||||
'installer',
|
||||
'pentester',
|
||||
'summarizer',
|
||||
'tool_call_fixer',
|
||||
'assistant'
|
||||
);
|
||||
|
||||
ALTER TABLE msgchains
|
||||
ALTER COLUMN type TYPE MSGCHAIN_TYPE_NEW USING type::text::MSGCHAIN_TYPE_NEW;
|
||||
|
||||
ALTER TABLE agentlogs
|
||||
ALTER COLUMN initiator TYPE MSGCHAIN_TYPE_NEW USING initiator::text::MSGCHAIN_TYPE_NEW,
|
||||
ALTER COLUMN executor TYPE MSGCHAIN_TYPE_NEW USING executor::text::MSGCHAIN_TYPE_NEW;
|
||||
|
||||
ALTER TABLE vecstorelogs
|
||||
ALTER COLUMN initiator TYPE MSGCHAIN_TYPE_NEW USING initiator::text::MSGCHAIN_TYPE_NEW,
|
||||
ALTER COLUMN executor TYPE MSGCHAIN_TYPE_NEW USING executor::text::MSGCHAIN_TYPE_NEW;
|
||||
|
||||
ALTER TABLE searchlogs
|
||||
ALTER COLUMN initiator TYPE MSGCHAIN_TYPE_NEW USING initiator::text::MSGCHAIN_TYPE_NEW,
|
||||
ALTER COLUMN executor TYPE MSGCHAIN_TYPE_NEW USING executor::text::MSGCHAIN_TYPE_NEW;
|
||||
|
||||
DROP TYPE MSGCHAIN_TYPE;
|
||||
|
||||
ALTER TYPE MSGCHAIN_TYPE_NEW RENAME TO MSGCHAIN_TYPE;
|
||||
|
||||
ALTER TABLE msgchains
|
||||
ALTER COLUMN type SET NOT NULL,
|
||||
ALTER COLUMN type SET DEFAULT 'primary_agent';
|
||||
|
||||
ALTER TABLE agentlogs
|
||||
ALTER COLUMN initiator SET NOT NULL,
|
||||
ALTER COLUMN initiator SET DEFAULT 'primary_agent',
|
||||
ALTER COLUMN executor SET NOT NULL,
|
||||
ALTER COLUMN executor SET DEFAULT 'primary_agent';
|
||||
|
||||
ALTER TABLE vecstorelogs
|
||||
ALTER COLUMN initiator SET NOT NULL,
|
||||
ALTER COLUMN initiator SET DEFAULT 'primary_agent',
|
||||
ALTER COLUMN executor SET NOT NULL,
|
||||
ALTER COLUMN executor SET DEFAULT 'primary_agent';
|
||||
|
||||
ALTER TABLE searchlogs
|
||||
ALTER COLUMN initiator SET NOT NULL,
|
||||
ALTER COLUMN initiator SET DEFAULT 'primary_agent',
|
||||
ALTER COLUMN executor SET NOT NULL,
|
||||
ALTER COLUMN executor SET DEFAULT 'primary_agent';
|
||||
|
||||
CREATE TYPE MSGLOG_TYPE_NEW AS ENUM (
|
||||
'answer',
|
||||
'report',
|
||||
'thoughts',
|
||||
'browser',
|
||||
'terminal',
|
||||
'file',
|
||||
'search',
|
||||
'advice',
|
||||
'ask',
|
||||
'input',
|
||||
'done'
|
||||
);
|
||||
|
||||
ALTER TABLE msglogs
|
||||
ALTER COLUMN type TYPE MSGLOG_TYPE_NEW USING type::text::MSGLOG_TYPE_NEW;
|
||||
|
||||
DROP TYPE MSGLOG_TYPE;
|
||||
|
||||
ALTER TYPE MSGLOG_TYPE_NEW RENAME TO MSGLOG_TYPE;
|
||||
|
||||
ALTER TABLE msglogs
|
||||
ALTER COLUMN type SET NOT NULL;
|
||||
|
||||
CREATE TYPE ASSISTANT_STATUS AS ENUM ('created','running','waiting','finished','failed');
|
||||
|
||||
CREATE TABLE assistants (
|
||||
id BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
status ASSISTANT_STATUS NOT NULL DEFAULT 'created',
|
||||
title TEXT NOT NULL DEFAULT 'untitled',
|
||||
model TEXT NOT NULL,
|
||||
model_provider TEXT NOT NULL,
|
||||
language TEXT NOT NULL,
|
||||
functions JSON NOT NULL DEFAULT '{}',
|
||||
prompts JSON NOT NULL,
|
||||
trace_id TEXT NULL,
|
||||
flow_id BIGINT NOT NULL REFERENCES flows(id) ON DELETE CASCADE,
|
||||
use_agents BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
msgchain_id BIGINT NULL REFERENCES msgchains(id) ON DELETE CASCADE,
|
||||
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
||||
deleted_at TIMESTAMPTZ NULL
|
||||
);
|
||||
|
||||
CREATE INDEX assistants_status_idx ON assistants(status);
|
||||
CREATE INDEX assistants_title_idx ON assistants(title);
|
||||
CREATE INDEX assistants_model_provider_idx ON assistants(model_provider);
|
||||
CREATE INDEX assistants_trace_id_idx ON assistants(trace_id);
|
||||
CREATE INDEX assistants_flow_id_idx ON assistants(flow_id);
|
||||
CREATE INDEX assistants_msgchain_id_idx ON assistants(msgchain_id);
|
||||
|
||||
CREATE TABLE assistantlogs (
|
||||
id BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
type MSGLOG_TYPE NOT NULL,
|
||||
message TEXT NOT NULL,
|
||||
result TEXT NOT NULL DEFAULT '',
|
||||
result_format MSGLOG_RESULT_FORMAT NOT NULL DEFAULT 'plain',
|
||||
flow_id BIGINT NOT NULL REFERENCES flows(id) ON DELETE CASCADE,
|
||||
assistant_id BIGINT NOT NULL REFERENCES assistants(id) ON DELETE CASCADE,
|
||||
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE INDEX assistantlogs_type_idx ON assistantlogs(type);
|
||||
CREATE INDEX assistantlogs_message_idx ON assistantlogs(message);
|
||||
CREATE INDEX assistantlogs_result_format_idx ON assistantlogs(result_format);
|
||||
CREATE INDEX assistantlogs_flow_id_idx ON assistantlogs(flow_id);
|
||||
CREATE INDEX assistantlogs_assistant_id_idx ON assistantlogs(assistant_id);
|
||||
|
||||
CREATE OR REPLACE TRIGGER update_assistants_modified
|
||||
BEFORE UPDATE ON assistants
|
||||
FOR EACH ROW EXECUTE PROCEDURE update_modified_column();
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
DROP TABLE assistants;
|
||||
DROP TABLE assistantlogs;
|
||||
DROP TYPE ASSISTANT_STATUS;
|
||||
|
||||
DELETE FROM privileges WHERE name IN (
|
||||
'assistants.admin',
|
||||
'assistants.create',
|
||||
'assistants.delete',
|
||||
'assistants.edit',
|
||||
'assistants.view',
|
||||
'assistants.subscribe',
|
||||
'assistantlogs.admin',
|
||||
'assistantlogs.view',
|
||||
'assistantlogs.subscribe'
|
||||
);
|
||||
|
||||
DELETE FROM msgchains WHERE type = 'assistant';
|
||||
|
||||
ALTER TABLE msgchains ALTER COLUMN type DROP DEFAULT;
|
||||
ALTER TABLE agentlogs ALTER COLUMN initiator DROP DEFAULT;
|
||||
ALTER TABLE agentlogs ALTER COLUMN executor DROP DEFAULT;
|
||||
ALTER TABLE vecstorelogs ALTER COLUMN initiator DROP DEFAULT;
|
||||
ALTER TABLE vecstorelogs ALTER COLUMN executor DROP DEFAULT;
|
||||
ALTER TABLE searchlogs ALTER COLUMN initiator DROP DEFAULT;
|
||||
ALTER TABLE searchlogs ALTER COLUMN executor DROP DEFAULT;
|
||||
|
||||
CREATE TYPE MSGCHAIN_TYPE_NEW AS ENUM (
|
||||
'primary_agent',
|
||||
'reporter',
|
||||
'generator',
|
||||
'refiner',
|
||||
'reflector',
|
||||
'enricher',
|
||||
'adviser',
|
||||
'coder',
|
||||
'memorist',
|
||||
'searcher',
|
||||
'installer',
|
||||
'pentester',
|
||||
'summarizer',
|
||||
'tool_call_fixer'
|
||||
);
|
||||
|
||||
ALTER TABLE msgchains
|
||||
ALTER COLUMN type TYPE MSGCHAIN_TYPE_NEW USING
|
||||
CASE
|
||||
WHEN type::text = 'assistant' THEN 'primary_agent'::text
|
||||
ELSE type::text
|
||||
END::MSGCHAIN_TYPE_NEW;
|
||||
|
||||
ALTER TABLE agentlogs
|
||||
ALTER COLUMN initiator TYPE MSGCHAIN_TYPE_NEW USING
|
||||
CASE
|
||||
WHEN initiator::text = 'assistant' THEN 'primary_agent'::text
|
||||
ELSE initiator::text
|
||||
END::MSGCHAIN_TYPE_NEW,
|
||||
ALTER COLUMN executor TYPE MSGCHAIN_TYPE_NEW USING
|
||||
CASE
|
||||
WHEN executor::text = 'assistant' THEN 'primary_agent'::text
|
||||
ELSE executor::text
|
||||
END::MSGCHAIN_TYPE_NEW;
|
||||
|
||||
ALTER TABLE vecstorelogs
|
||||
ALTER COLUMN initiator TYPE MSGCHAIN_TYPE_NEW USING
|
||||
CASE
|
||||
WHEN initiator::text = 'assistant' THEN 'primary_agent'::text
|
||||
ELSE initiator::text
|
||||
END::MSGCHAIN_TYPE_NEW,
|
||||
ALTER COLUMN executor TYPE MSGCHAIN_TYPE_NEW USING
|
||||
CASE
|
||||
WHEN executor::text = 'assistant' THEN 'primary_agent'::text
|
||||
ELSE executor::text
|
||||
END::MSGCHAIN_TYPE_NEW;
|
||||
|
||||
ALTER TABLE searchlogs
|
||||
ALTER COLUMN initiator TYPE MSGCHAIN_TYPE_NEW USING
|
||||
CASE
|
||||
WHEN initiator::text = 'assistant' THEN 'primary_agent'::text
|
||||
ELSE initiator::text
|
||||
END::MSGCHAIN_TYPE_NEW,
|
||||
ALTER COLUMN executor TYPE MSGCHAIN_TYPE_NEW USING
|
||||
CASE
|
||||
WHEN executor::text = 'assistant' THEN 'primary_agent'::text
|
||||
ELSE executor::text
|
||||
END::MSGCHAIN_TYPE_NEW;
|
||||
|
||||
DROP TYPE MSGCHAIN_TYPE;
|
||||
|
||||
ALTER TYPE MSGCHAIN_TYPE_NEW RENAME TO MSGCHAIN_TYPE;
|
||||
|
||||
ALTER TABLE msgchains
|
||||
ALTER COLUMN type SET NOT NULL,
|
||||
ALTER COLUMN type SET DEFAULT 'primary_agent';
|
||||
|
||||
ALTER TABLE agentlogs
|
||||
ALTER COLUMN initiator SET NOT NULL,
|
||||
ALTER COLUMN initiator SET DEFAULT 'primary_agent',
|
||||
ALTER COLUMN executor SET NOT NULL,
|
||||
ALTER COLUMN executor SET DEFAULT 'primary_agent';
|
||||
|
||||
ALTER TABLE vecstorelogs
|
||||
ALTER COLUMN initiator SET NOT NULL,
|
||||
ALTER COLUMN initiator SET DEFAULT 'primary_agent',
|
||||
ALTER COLUMN executor SET NOT NULL,
|
||||
ALTER COLUMN executor SET DEFAULT 'primary_agent';
|
||||
|
||||
ALTER TABLE searchlogs
|
||||
ALTER COLUMN initiator SET NOT NULL,
|
||||
ALTER COLUMN initiator SET DEFAULT 'primary_agent',
|
||||
ALTER COLUMN executor SET NOT NULL,
|
||||
ALTER COLUMN executor SET DEFAULT 'primary_agent';
|
||||
|
||||
DELETE FROM msglogs WHERE type = 'answer' OR type = 'report';
|
||||
|
||||
CREATE TYPE MSGLOG_TYPE_NEW AS ENUM (
|
||||
'thoughts',
|
||||
'browser',
|
||||
'terminal',
|
||||
'file',
|
||||
'search',
|
||||
'advice',
|
||||
'ask',
|
||||
'input',
|
||||
'done'
|
||||
);
|
||||
|
||||
ALTER TABLE msglogs
|
||||
ALTER COLUMN type TYPE MSGLOG_TYPE_NEW USING type::text::MSGLOG_TYPE_NEW;
|
||||
|
||||
DROP TYPE MSGLOG_TYPE;
|
||||
|
||||
ALTER TYPE MSGLOG_TYPE_NEW RENAME TO MSGLOG_TYPE;
|
||||
|
||||
ALTER TABLE msglogs
|
||||
ALTER COLUMN type SET NOT NULL;
|
||||
-- +goose StatementEnd
|
||||
@@ -0,0 +1,13 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
ALTER TABLE subtasks ADD COLUMN context TEXT NULL DEFAULT '';
|
||||
|
||||
UPDATE subtasks SET context = '';
|
||||
|
||||
ALTER TABLE subtasks ALTER COLUMN context SET NOT NULL;
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
ALTER TABLE subtasks DROP COLUMN context;
|
||||
-- +goose StatementEnd
|
||||
@@ -0,0 +1,13 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
ALTER TABLE msglogs ADD COLUMN thinking TEXT NULL;
|
||||
|
||||
ALTER TABLE assistantlogs ADD COLUMN thinking TEXT NULL;
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
ALTER TABLE msglogs DROP COLUMN thinking;
|
||||
|
||||
ALTER TABLE assistantlogs DROP COLUMN thinking;
|
||||
-- +goose StatementEnd
|
||||
@@ -0,0 +1,27 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
CREATE EXTENSION IF NOT EXISTS pg_trgm;
|
||||
|
||||
DROP INDEX IF EXISTS assistantlogs_message_idx;
|
||||
CREATE INDEX assistantlogs_message_idx ON assistantlogs USING GIN (message gin_trgm_ops);
|
||||
CREATE INDEX assistantlogs_result_idx ON assistantlogs USING GIN (result gin_trgm_ops);
|
||||
CREATE INDEX assistantlogs_thinking_idx ON assistantlogs USING GIN (thinking gin_trgm_ops);
|
||||
|
||||
DROP INDEX IF EXISTS msglogs_message_idx;
|
||||
CREATE INDEX msglogs_message_idx ON msglogs USING GIN (message gin_trgm_ops);
|
||||
CREATE INDEX msglogs_result_idx ON msglogs USING GIN (result gin_trgm_ops);
|
||||
CREATE INDEX msglogs_thinking_idx ON msglogs USING GIN (thinking gin_trgm_ops);
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
DROP INDEX IF EXISTS assistantlogs_message_idx;
|
||||
DROP INDEX IF EXISTS assistantlogs_result_idx;
|
||||
DROP INDEX IF EXISTS assistantlogs_thinking_idx;
|
||||
CREATE INDEX assistantlogs_message_idx ON assistantlogs(message);
|
||||
|
||||
DROP INDEX IF EXISTS msglogs_message_idx;
|
||||
DROP INDEX IF EXISTS msglogs_result_idx;
|
||||
DROP INDEX IF EXISTS msglogs_thinking_idx;
|
||||
CREATE INDEX msglogs_message_idx ON msglogs(message);
|
||||
-- +goose StatementEnd
|
||||
@@ -0,0 +1,15 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
INSERT INTO privileges (role_id, name) VALUES
|
||||
(1, 'settings.admin'),
|
||||
(1, 'settings.view'),
|
||||
(2, 'settings.view');
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
DELETE FROM privileges WHERE name IN (
|
||||
'settings.admin',
|
||||
'settings.view'
|
||||
);
|
||||
-- +goose StatementEnd
|
||||
@@ -0,0 +1,209 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
INSERT INTO privileges (role_id, name) VALUES
|
||||
(1, 'settings.providers.admin'),
|
||||
(1, 'settings.providers.view'),
|
||||
(1, 'settings.providers.edit'),
|
||||
(1, 'settings.providers.subscribe'),
|
||||
(1, 'settings.prompts.admin'),
|
||||
(1, 'settings.prompts.view'),
|
||||
(1, 'settings.prompts.edit'),
|
||||
(2, 'settings.providers.view'),
|
||||
(2, 'settings.providers.edit'),
|
||||
(2, 'settings.providers.subscribe'),
|
||||
(2, 'settings.prompts.view'),
|
||||
(2, 'settings.prompts.edit');
|
||||
|
||||
-- Replace old prompt permissions with new settings-namespaced ones
|
||||
DELETE FROM privileges WHERE name IN (
|
||||
'prompts.view',
|
||||
'prompts.edit'
|
||||
);
|
||||
|
||||
-- Move prompts from flow/assistant to separate table and load them each time from the database
|
||||
ALTER TABLE flows DROP COLUMN prompts;
|
||||
ALTER TABLE assistants DROP COLUMN prompts;
|
||||
|
||||
CREATE TYPE PROVIDER_TYPE AS ENUM (
|
||||
'openai',
|
||||
'anthropic',
|
||||
'gemini',
|
||||
'bedrock',
|
||||
'ollama',
|
||||
'custom'
|
||||
);
|
||||
|
||||
CREATE TABLE providers (
|
||||
id BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
user_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
type PROVIDER_TYPE NOT NULL,
|
||||
name TEXT NOT NULL,
|
||||
config JSON NOT NULL,
|
||||
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
||||
deleted_at TIMESTAMPTZ NULL
|
||||
);
|
||||
|
||||
CREATE INDEX providers_user_id_idx ON providers(user_id);
|
||||
CREATE INDEX providers_type_idx ON providers(type);
|
||||
CREATE INDEX providers_name_user_id_idx ON providers(name, user_id);
|
||||
CREATE UNIQUE INDEX providers_name_user_id_unique ON providers(name, user_id) WHERE deleted_at IS NULL;
|
||||
|
||||
-- Add model providers type column and separate name from type
|
||||
ALTER TABLE flows ADD COLUMN model_provider_type PROVIDER_TYPE NULL;
|
||||
UPDATE flows SET model_provider_type = model_provider::PROVIDER_TYPE;
|
||||
ALTER TABLE flows ALTER COLUMN model_provider_type SET NOT NULL;
|
||||
CREATE INDEX flows_model_provider_type_idx ON flows(model_provider_type);
|
||||
DROP INDEX IF EXISTS flows_model_provider_idx;
|
||||
ALTER TABLE flows RENAME COLUMN model_provider TO model_provider_name;
|
||||
CREATE INDEX flows_model_provider_name_idx ON flows(model_provider_name);
|
||||
|
||||
ALTER TABLE assistants ADD COLUMN model_provider_type PROVIDER_TYPE NULL;
|
||||
UPDATE assistants SET model_provider_type = model_provider::PROVIDER_TYPE;
|
||||
ALTER TABLE assistants ALTER COLUMN model_provider_type SET NOT NULL;
|
||||
CREATE INDEX assistants_model_provider_type_idx ON assistants(model_provider_type);
|
||||
DROP INDEX IF EXISTS assistants_model_provider_idx;
|
||||
ALTER TABLE assistants RENAME COLUMN model_provider TO model_provider_name;
|
||||
CREATE INDEX assistants_model_provider_name_idx ON assistants(model_provider_name);
|
||||
|
||||
-- ENUM values correspond to template files in backend/pkg/templates/prompts/
|
||||
CREATE TYPE PROMPT_TYPE AS ENUM (
|
||||
'primary_agent',
|
||||
'assistant',
|
||||
'pentester',
|
||||
'question_pentester',
|
||||
'coder',
|
||||
'question_coder',
|
||||
'installer',
|
||||
'question_installer',
|
||||
'searcher',
|
||||
'question_searcher',
|
||||
'memorist',
|
||||
'question_memorist',
|
||||
'adviser',
|
||||
'question_adviser',
|
||||
'generator',
|
||||
'subtasks_generator',
|
||||
'refiner',
|
||||
'subtasks_refiner',
|
||||
'reporter',
|
||||
'task_reporter',
|
||||
'reflector',
|
||||
'question_reflector',
|
||||
'enricher',
|
||||
'question_enricher',
|
||||
'toolcall_fixer',
|
||||
'input_toolcall_fixer',
|
||||
'summarizer',
|
||||
'image_chooser',
|
||||
'language_chooser',
|
||||
'flow_descriptor',
|
||||
'task_descriptor',
|
||||
'execution_logs',
|
||||
'full_execution_context',
|
||||
'short_execution_context'
|
||||
);
|
||||
|
||||
-- Validate existing prompt types are compatible with new ENUM before migration
|
||||
DO $$
|
||||
DECLARE
|
||||
invalid_types TEXT[];
|
||||
BEGIN
|
||||
SELECT ARRAY_AGG(DISTINCT type) INTO invalid_types
|
||||
FROM prompts
|
||||
WHERE type::TEXT NOT IN (
|
||||
'execution_logs', 'full_execution_context', 'short_execution_context',
|
||||
'question_enricher', 'question_adviser', 'question_coder', 'question_installer',
|
||||
'question_memorist', 'question_pentester', 'question_searcher', 'question_reflector',
|
||||
'input_toolcall_fixer', 'assistant', 'primary_agent', 'flow_descriptor',
|
||||
'task_descriptor', 'image_chooser', 'language_chooser', 'task_reporter',
|
||||
'toolcall_fixer', 'reporter', 'subtasks_generator', 'generator',
|
||||
'subtasks_refiner', 'refiner', 'enricher', 'reflector', 'adviser',
|
||||
'coder', 'installer', 'pentester', 'memorist', 'searcher', 'summarizer'
|
||||
);
|
||||
|
||||
IF array_length(invalid_types, 1) > 0 THEN
|
||||
RAISE EXCEPTION 'Found invalid prompt types that cannot be converted to ENUM: %',
|
||||
array_to_string(invalid_types, ', ');
|
||||
END IF;
|
||||
END$$;
|
||||
|
||||
DROP INDEX IF EXISTS prompts_type_idx;
|
||||
DROP INDEX IF EXISTS prompts_prompt_idx;
|
||||
|
||||
ALTER TABLE prompts
|
||||
ALTER COLUMN type TYPE PROMPT_TYPE USING type::text::PROMPT_TYPE;
|
||||
|
||||
CREATE INDEX prompts_type_idx ON prompts(type);
|
||||
|
||||
ALTER TABLE prompts
|
||||
ADD COLUMN created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
||||
ADD COLUMN updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP;
|
||||
|
||||
CREATE OR REPLACE TRIGGER update_providers_modified
|
||||
BEFORE UPDATE ON providers
|
||||
FOR EACH ROW EXECUTE PROCEDURE update_modified_column();
|
||||
|
||||
CREATE OR REPLACE TRIGGER update_prompts_modified
|
||||
BEFORE UPDATE ON prompts
|
||||
FOR EACH ROW EXECUTE PROCEDURE update_modified_column();
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
ALTER TABLE flows DROP COLUMN model_provider_type;
|
||||
ALTER TABLE assistants DROP COLUMN model_provider_type;
|
||||
ALTER TABLE flows RENAME COLUMN model_provider_name TO model_provider;
|
||||
ALTER TABLE assistants RENAME COLUMN model_provider_name TO model_provider;
|
||||
|
||||
-- Delete unsupported model providers
|
||||
DROP INDEX IF EXISTS flows_model_provider_name_idx;
|
||||
DROP INDEX IF EXISTS assistants_model_provider_name_idx;
|
||||
DELETE FROM flows WHERE model_provider NOT IN ('openai', 'anthropic', 'custom');
|
||||
DELETE FROM assistants WHERE model_provider NOT IN ('openai', 'anthropic', 'custom');
|
||||
CREATE INDEX flows_model_provider_idx ON flows(model_provider);
|
||||
CREATE INDEX assistants_model_provider_idx ON assistants(model_provider);
|
||||
|
||||
DROP TABLE providers;
|
||||
DROP TYPE PROVIDER_TYPE;
|
||||
|
||||
DELETE FROM privileges WHERE name IN (
|
||||
'settings.providers.admin',
|
||||
'settings.providers.view',
|
||||
'settings.providers.edit',
|
||||
'settings.providers.subscribe',
|
||||
'settings.prompts.admin',
|
||||
'settings.prompts.view',
|
||||
'settings.prompts.edit'
|
||||
);
|
||||
|
||||
INSERT INTO privileges (role_id, name) VALUES
|
||||
(1, 'prompts.view'),
|
||||
(1, 'prompts.edit'),
|
||||
(2, 'prompts.view');
|
||||
|
||||
-- Convert prompts.type back to TEXT while preserving user data
|
||||
DROP INDEX IF EXISTS prompts_type_idx;
|
||||
|
||||
ALTER TABLE prompts
|
||||
ALTER COLUMN type TYPE TEXT USING type::text;
|
||||
|
||||
CREATE INDEX prompts_type_idx ON prompts(type);
|
||||
CREATE INDEX prompts_prompt_idx ON prompts(prompt);
|
||||
|
||||
DROP TRIGGER IF EXISTS update_prompts_modified ON prompts;
|
||||
ALTER TABLE prompts DROP COLUMN created_at;
|
||||
ALTER TABLE prompts DROP COLUMN updated_at;
|
||||
|
||||
DROP TYPE PROMPT_TYPE;
|
||||
|
||||
-- Restore prompts to flows/assistants
|
||||
ALTER TABLE flows ADD COLUMN prompts JSON NULL;
|
||||
ALTER TABLE assistants ADD COLUMN prompts JSON NULL;
|
||||
|
||||
UPDATE flows SET prompts = '{}';
|
||||
UPDATE assistants SET prompts = '{}';
|
||||
|
||||
ALTER TABLE flows ALTER COLUMN prompts SET NOT NULL;
|
||||
ALTER TABLE assistants ALTER COLUMN prompts SET NOT NULL;
|
||||
-- +goose StatementEnd
|
||||
@@ -0,0 +1,50 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
-- Add searxng to the searchengine_type enum
|
||||
CREATE TYPE SEARCHENGINE_TYPE_NEW AS ENUM (
|
||||
'google',
|
||||
'tavily',
|
||||
'traversaal',
|
||||
'browser',
|
||||
'duckduckgo',
|
||||
'perplexity',
|
||||
'searxng'
|
||||
);
|
||||
|
||||
-- Update the searchlogs table to use the new enum type
|
||||
ALTER TABLE searchlogs
|
||||
ALTER COLUMN engine TYPE SEARCHENGINE_TYPE_NEW USING engine::text::SEARCHENGINE_TYPE_NEW;
|
||||
|
||||
-- Drop the old type and rename the new one
|
||||
DROP TYPE SEARCHENGINE_TYPE;
|
||||
ALTER TYPE SEARCHENGINE_TYPE_NEW RENAME TO SEARCHENGINE_TYPE;
|
||||
|
||||
-- Set the column as NOT NULL
|
||||
ALTER TABLE searchlogs
|
||||
ALTER COLUMN engine SET NOT NULL;
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
-- Revert the changes by removing searxng from the enum
|
||||
CREATE TYPE SEARCHENGINE_TYPE_NEW AS ENUM (
|
||||
'google',
|
||||
'tavily',
|
||||
'traversaal',
|
||||
'browser',
|
||||
'duckduckgo',
|
||||
'perplexity'
|
||||
);
|
||||
|
||||
-- Update the searchlogs table to use the new enum type
|
||||
ALTER TABLE searchlogs
|
||||
ALTER COLUMN engine TYPE SEARCHENGINE_TYPE_NEW USING engine::text::SEARCHENGINE_TYPE_NEW;
|
||||
|
||||
-- Drop the old type and rename the new one
|
||||
DROP TYPE SEARCHENGINE_TYPE;
|
||||
ALTER TYPE SEARCHENGINE_TYPE_NEW RENAME TO SEARCHENGINE_TYPE;
|
||||
|
||||
-- Set the column as NOT NULL
|
||||
ALTER TABLE searchlogs
|
||||
ALTER COLUMN engine SET NOT NULL;
|
||||
-- +goose StatementEnd
|
||||
@@ -0,0 +1,9 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
DROP INDEX IF EXISTS tasks_input_idx;
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
CREATE INDEX tasks_input_idx ON tasks(input);
|
||||
-- +goose StatementEnd
|
||||
@@ -0,0 +1,11 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
DROP INDEX IF EXISTS tasks_result_idx;
|
||||
DROP INDEX IF EXISTS subtasks_result_idx;
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
CREATE INDEX tasks_result_idx ON tasks(result);
|
||||
CREATE INDEX subtasks_result_idx ON subtasks(result);
|
||||
-- +goose StatementEnd
|
||||
@@ -0,0 +1,9 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
DROP INDEX IF EXISTS subtasks_description_idx;
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
CREATE INDEX subtasks_description_idx ON subtasks(description);
|
||||
-- +goose StatementEnd
|
||||
@@ -0,0 +1,125 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
ALTER TABLE flows ADD COLUMN tool_call_id_template TEXT NULL;
|
||||
ALTER TABLE assistants ADD COLUMN tool_call_id_template TEXT NULL;
|
||||
|
||||
UPDATE flows SET tool_call_id_template = 'call_{r:24:x}';
|
||||
UPDATE assistants SET tool_call_id_template = 'call_{r:24:x}';
|
||||
|
||||
ALTER TABLE flows ALTER COLUMN tool_call_id_template SET NOT NULL;
|
||||
ALTER TABLE assistants ALTER COLUMN tool_call_id_template SET NOT NULL;
|
||||
|
||||
CREATE INDEX flows_tool_call_id_template_idx ON flows(tool_call_id_template) WHERE tool_call_id_template IS NOT NULL;
|
||||
CREATE INDEX assistants_tool_call_id_template_idx ON assistants(tool_call_id_template) WHERE tool_call_id_template IS NOT NULL;
|
||||
|
||||
-- Add new prompt types for tool call ID detection
|
||||
CREATE TYPE PROMPT_TYPE_NEW AS ENUM (
|
||||
'primary_agent',
|
||||
'assistant',
|
||||
'pentester',
|
||||
'question_pentester',
|
||||
'coder',
|
||||
'question_coder',
|
||||
'installer',
|
||||
'question_installer',
|
||||
'searcher',
|
||||
'question_searcher',
|
||||
'memorist',
|
||||
'question_memorist',
|
||||
'adviser',
|
||||
'question_adviser',
|
||||
'generator',
|
||||
'subtasks_generator',
|
||||
'refiner',
|
||||
'subtasks_refiner',
|
||||
'reporter',
|
||||
'task_reporter',
|
||||
'reflector',
|
||||
'question_reflector',
|
||||
'enricher',
|
||||
'question_enricher',
|
||||
'toolcall_fixer',
|
||||
'input_toolcall_fixer',
|
||||
'summarizer',
|
||||
'image_chooser',
|
||||
'language_chooser',
|
||||
'flow_descriptor',
|
||||
'task_descriptor',
|
||||
'execution_logs',
|
||||
'full_execution_context',
|
||||
'short_execution_context',
|
||||
'tool_call_id_collector',
|
||||
'tool_call_id_detector'
|
||||
);
|
||||
|
||||
-- Update the searchlogs table to use the new enum type
|
||||
ALTER TABLE prompts
|
||||
ALTER COLUMN type TYPE PROMPT_TYPE_NEW USING type::text::PROMPT_TYPE_NEW;
|
||||
|
||||
-- Drop the old type and rename the new one
|
||||
DROP TYPE PROMPT_TYPE;
|
||||
ALTER TYPE PROMPT_TYPE_NEW RENAME TO PROMPT_TYPE;
|
||||
|
||||
-- Set the column as NOT NULL
|
||||
ALTER TABLE prompts
|
||||
ALTER COLUMN type SET NOT NULL;
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
DROP INDEX IF EXISTS flows_tool_call_id_template_idx;
|
||||
DROP INDEX IF EXISTS assistants_tool_call_id_template_idx;
|
||||
|
||||
ALTER TABLE flows DROP COLUMN IF EXISTS tool_call_id_template;
|
||||
ALTER TABLE assistants DROP COLUMN IF EXISTS tool_call_id_template;
|
||||
|
||||
-- Revert the changes by removing tool call ID collector and detector from the enum
|
||||
CREATE TYPE PROMPT_TYPE_NEW AS ENUM (
|
||||
'primary_agent',
|
||||
'assistant',
|
||||
'pentester',
|
||||
'question_pentester',
|
||||
'coder',
|
||||
'question_coder',
|
||||
'installer',
|
||||
'question_installer',
|
||||
'searcher',
|
||||
'question_searcher',
|
||||
'memorist',
|
||||
'question_memorist',
|
||||
'adviser',
|
||||
'question_adviser',
|
||||
'generator',
|
||||
'subtasks_generator',
|
||||
'refiner',
|
||||
'subtasks_refiner',
|
||||
'reporter',
|
||||
'task_reporter',
|
||||
'reflector',
|
||||
'question_reflector',
|
||||
'enricher',
|
||||
'question_enricher',
|
||||
'toolcall_fixer',
|
||||
'input_toolcall_fixer',
|
||||
'summarizer',
|
||||
'image_chooser',
|
||||
'language_chooser',
|
||||
'flow_descriptor',
|
||||
'task_descriptor',
|
||||
'execution_logs',
|
||||
'full_execution_context',
|
||||
'short_execution_context'
|
||||
);
|
||||
|
||||
-- Update the prompts table to use the new enum type
|
||||
ALTER TABLE prompts
|
||||
ALTER COLUMN type TYPE PROMPT_TYPE_NEW USING type::text::PROMPT_TYPE_NEW;
|
||||
|
||||
-- Drop the old type and rename the new one
|
||||
DROP TYPE PROMPT_TYPE;
|
||||
ALTER TYPE PROMPT_TYPE_NEW RENAME TO PROMPT_TYPE;
|
||||
|
||||
-- Set the column as NOT NULL
|
||||
ALTER TABLE prompts
|
||||
ALTER COLUMN type SET NOT NULL;
|
||||
-- +goose StatementEnd
|
||||
@@ -0,0 +1,258 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
-- Add usage tracking fields to msgchains
|
||||
ALTER TABLE msgchains ADD COLUMN usage_cache_in BIGINT NOT NULL DEFAULT 0;
|
||||
ALTER TABLE msgchains ADD COLUMN usage_cache_out BIGINT NOT NULL DEFAULT 0;
|
||||
ALTER TABLE msgchains ADD COLUMN usage_cost_in DOUBLE PRECISION NOT NULL DEFAULT 0.0;
|
||||
ALTER TABLE msgchains ADD COLUMN usage_cost_out DOUBLE PRECISION NOT NULL DEFAULT 0.0;
|
||||
|
||||
-- Add duration tracking to msgchains (nullable first)
|
||||
ALTER TABLE msgchains ADD COLUMN duration_seconds DOUBLE PRECISION NULL;
|
||||
|
||||
-- Calculate duration for existing msgchains records
|
||||
UPDATE msgchains
|
||||
SET duration_seconds = EXTRACT(EPOCH FROM (updated_at - created_at))
|
||||
WHERE updated_at > created_at;
|
||||
|
||||
-- Set remaining NULL values to 0.0
|
||||
UPDATE msgchains
|
||||
SET duration_seconds = 0.0
|
||||
WHERE duration_seconds IS NULL;
|
||||
|
||||
-- Make column NOT NULL with default
|
||||
ALTER TABLE msgchains ALTER COLUMN duration_seconds SET NOT NULL;
|
||||
ALTER TABLE msgchains ALTER COLUMN duration_seconds SET DEFAULT 0.0;
|
||||
|
||||
-- Add duration tracking to toolcalls (nullable first)
|
||||
ALTER TABLE toolcalls ADD COLUMN duration_seconds DOUBLE PRECISION NULL;
|
||||
|
||||
-- Calculate duration for existing toolcalls records (finished and failed only)
|
||||
UPDATE toolcalls
|
||||
SET duration_seconds = EXTRACT(EPOCH FROM (updated_at - created_at))
|
||||
WHERE updated_at > created_at AND status IN ('finished', 'failed');
|
||||
|
||||
-- Set remaining NULL values to 0.0
|
||||
UPDATE toolcalls
|
||||
SET duration_seconds = 0.0
|
||||
WHERE duration_seconds IS NULL;
|
||||
|
||||
-- Make column NOT NULL with default
|
||||
ALTER TABLE toolcalls ALTER COLUMN duration_seconds SET NOT NULL;
|
||||
ALTER TABLE toolcalls ALTER COLUMN duration_seconds SET DEFAULT 0.0;
|
||||
|
||||
-- Add task and subtask references to termlogs for better hierarchical tracking
|
||||
ALTER TABLE termlogs ADD COLUMN flow_id BIGINT NULL REFERENCES flows(id) ON DELETE CASCADE;
|
||||
ALTER TABLE termlogs ADD COLUMN task_id BIGINT NULL REFERENCES tasks(id) ON DELETE CASCADE;
|
||||
ALTER TABLE termlogs ADD COLUMN subtask_id BIGINT NULL REFERENCES subtasks(id) ON DELETE CASCADE;
|
||||
|
||||
-- Fill flow_id from related containers
|
||||
UPDATE termlogs tl
|
||||
SET flow_id = c.flow_id
|
||||
FROM containers c
|
||||
WHERE tl.container_id = c.id AND tl.flow_id IS NULL;
|
||||
|
||||
-- For any remaining NULL flow_id (shouldn't happen due to CASCADE, but just in case)
|
||||
-- Fill with the first available flow_id
|
||||
UPDATE termlogs
|
||||
SET flow_id = (SELECT id FROM flows ORDER BY id LIMIT 1)
|
||||
WHERE flow_id IS NULL;
|
||||
|
||||
-- Delete orphaned records if any still have NULL flow_id (no flows exist)
|
||||
-- This shouldn't happen in practice due to CASCADE DELETE
|
||||
DELETE FROM termlogs WHERE flow_id IS NULL;
|
||||
|
||||
-- Now make flow_id NOT NULL
|
||||
ALTER TABLE termlogs ALTER COLUMN flow_id SET NOT NULL;
|
||||
|
||||
-- Add task and subtask references to screenshots for better hierarchical tracking
|
||||
-- Note: flow_id already exists as NOT NULL in screenshots table
|
||||
ALTER TABLE screenshots ADD COLUMN task_id BIGINT NULL REFERENCES tasks(id) ON DELETE CASCADE;
|
||||
ALTER TABLE screenshots ADD COLUMN subtask_id BIGINT NULL REFERENCES subtasks(id) ON DELETE CASCADE;
|
||||
|
||||
-- Create indexes for termlogs foreign keys
|
||||
CREATE INDEX termlogs_flow_id_idx ON termlogs(flow_id);
|
||||
CREATE INDEX termlogs_task_id_idx ON termlogs(task_id);
|
||||
CREATE INDEX termlogs_subtask_id_idx ON termlogs(subtask_id);
|
||||
|
||||
-- Create indexes for screenshots foreign keys
|
||||
CREATE INDEX screenshots_task_id_idx ON screenshots(task_id);
|
||||
CREATE INDEX screenshots_subtask_id_idx ON screenshots(subtask_id);
|
||||
|
||||
-- Index for soft delete filtering on flows (used in all analytics queries)
|
||||
-- Using partial index because we mostly query non-deleted flows
|
||||
CREATE INDEX flows_deleted_at_idx ON flows(deleted_at) WHERE deleted_at IS NULL;
|
||||
|
||||
-- Index for time-based analytics queries
|
||||
CREATE INDEX msgchains_created_at_idx ON msgchains(created_at);
|
||||
|
||||
-- Index for grouping by model provider
|
||||
CREATE INDEX msgchains_model_provider_idx ON msgchains(model_provider);
|
||||
|
||||
-- Index for grouping by model
|
||||
CREATE INDEX msgchains_model_idx ON msgchains(model);
|
||||
|
||||
-- Composite index for queries that group by both model and provider
|
||||
CREATE INDEX msgchains_model_provider_composite_idx ON msgchains(model, model_provider);
|
||||
|
||||
-- Composite index for time-based queries with flow filtering
|
||||
-- This helps queries that filter by created_at AND join with flows
|
||||
CREATE INDEX msgchains_created_at_flow_id_idx ON msgchains(created_at, flow_id);
|
||||
|
||||
-- Composite index for type-based analytics with flow filtering
|
||||
CREATE INDEX msgchains_type_flow_id_idx ON msgchains(type, flow_id);
|
||||
|
||||
-- ==================== Toolcalls Analytics Indexes ====================
|
||||
|
||||
-- Index for time-based toolcalls analytics queries
|
||||
CREATE INDEX toolcalls_created_at_idx ON toolcalls(created_at);
|
||||
|
||||
-- Index for updated_at to help with duration calculations
|
||||
CREATE INDEX toolcalls_updated_at_idx ON toolcalls(updated_at);
|
||||
|
||||
-- Composite index for time-based queries with flow filtering
|
||||
CREATE INDEX toolcalls_created_at_flow_id_idx ON toolcalls(created_at, flow_id);
|
||||
|
||||
-- Composite index for function-based analytics with flow filtering
|
||||
CREATE INDEX toolcalls_name_flow_id_idx ON toolcalls(name, flow_id);
|
||||
|
||||
-- Composite index for status and timestamps (for duration calculations)
|
||||
CREATE INDEX toolcalls_status_updated_at_idx ON toolcalls(status, updated_at);
|
||||
|
||||
-- ==================== Flows Analytics Indexes ====================
|
||||
|
||||
-- Index for time-based flows analytics queries
|
||||
CREATE INDEX flows_created_at_idx ON flows(created_at) WHERE deleted_at IS NULL;
|
||||
|
||||
-- Index for tasks time-based analytics
|
||||
CREATE INDEX tasks_created_at_idx ON tasks(created_at);
|
||||
|
||||
-- Index for subtasks time-based analytics
|
||||
CREATE INDEX subtasks_created_at_idx ON subtasks(created_at);
|
||||
|
||||
-- Composite index for tasks with flow filtering
|
||||
CREATE INDEX tasks_flow_id_created_at_idx ON tasks(flow_id, created_at);
|
||||
|
||||
-- Composite index for subtasks with task filtering
|
||||
CREATE INDEX subtasks_task_id_created_at_idx ON subtasks(task_id, created_at);
|
||||
|
||||
-- Add usage privileges
|
||||
INSERT INTO privileges (role_id, name) VALUES
|
||||
(1, 'usage.admin'),
|
||||
(1, 'usage.view'),
|
||||
(2, 'usage.view')
|
||||
ON CONFLICT DO NOTHING;
|
||||
|
||||
-- ==================== Assistants Analytics Indexes ====================
|
||||
|
||||
-- Partial index for soft delete filtering (used in almost all assistants queries)
|
||||
CREATE INDEX assistants_deleted_at_idx ON assistants(deleted_at) WHERE deleted_at IS NULL;
|
||||
|
||||
-- Index for time-based queries and sorting
|
||||
CREATE INDEX assistants_created_at_idx ON assistants(created_at);
|
||||
|
||||
-- Composite index for flow-scoped queries with soft delete filter
|
||||
-- Optimizes: SELECT ... FROM assistants WHERE flow_id = $1 AND deleted_at IS NULL
|
||||
CREATE INDEX assistants_flow_id_deleted_at_idx ON assistants(flow_id, deleted_at) WHERE deleted_at IS NULL;
|
||||
|
||||
-- Composite index for temporal analytics queries
|
||||
-- Optimizes: GetFlowsStatsByDay* queries that join assistants with DATE(created_at) condition
|
||||
CREATE INDEX assistants_flow_id_created_at_idx ON assistants(flow_id, created_at) WHERE deleted_at IS NULL;
|
||||
|
||||
-- ==================== Additional Analytics Indexes ====================
|
||||
|
||||
-- Composite index for subtasks filtering by task and status
|
||||
-- Optimizes: GetTaskPlannedSubtasks, GetTaskCompletedSubtasks, analytics calculations
|
||||
CREATE INDEX subtasks_task_id_status_idx ON subtasks(task_id, status);
|
||||
|
||||
-- Composite index for toolcalls filtering by flow and status
|
||||
-- Optimizes: Analytics queries counting finished/failed toolcalls per flow
|
||||
CREATE INDEX toolcalls_flow_id_status_idx ON toolcalls(flow_id, status);
|
||||
|
||||
-- Composite index for msgchains type-based analytics with hierarchy
|
||||
-- Optimizes: Queries searching for specific msgchain types at task/subtask level
|
||||
CREATE INDEX msgchains_type_task_id_subtask_id_idx ON msgchains(type, task_id, subtask_id);
|
||||
|
||||
-- Composite index for tasks with flow and status filtering
|
||||
-- Optimizes: Flow-scoped task queries with status filtering
|
||||
CREATE INDEX tasks_flow_id_status_idx ON tasks(flow_id, status);
|
||||
|
||||
-- Composite index for subtasks with status filtering (extended version)
|
||||
-- Optimizes: Subtask analytics excluding created/waiting subtasks
|
||||
CREATE INDEX subtasks_status_created_at_idx ON subtasks(status, created_at);
|
||||
|
||||
-- Composite index for toolcalls analytics by name and status
|
||||
-- Optimizes: GetToolcallsStatsByFunction queries (filtering by status)
|
||||
CREATE INDEX toolcalls_name_status_idx ON toolcalls(name, status);
|
||||
|
||||
-- Composite index for msgchains analytics by type and created_at
|
||||
-- Optimizes: Time-based analytics grouped by msgchain type
|
||||
CREATE INDEX msgchains_type_created_at_idx ON msgchains(type, created_at);
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
-- Drop termlogs indexes and columns
|
||||
DROP INDEX IF EXISTS termlogs_flow_id_idx;
|
||||
DROP INDEX IF EXISTS termlogs_task_id_idx;
|
||||
DROP INDEX IF EXISTS termlogs_subtask_id_idx;
|
||||
ALTER TABLE termlogs DROP COLUMN flow_id;
|
||||
ALTER TABLE termlogs DROP COLUMN task_id;
|
||||
ALTER TABLE termlogs DROP COLUMN subtask_id;
|
||||
|
||||
-- Drop screenshots indexes and columns
|
||||
DROP INDEX IF EXISTS screenshots_task_id_idx;
|
||||
DROP INDEX IF EXISTS screenshots_subtask_id_idx;
|
||||
ALTER TABLE screenshots DROP COLUMN task_id;
|
||||
ALTER TABLE screenshots DROP COLUMN subtask_id;
|
||||
|
||||
-- Drop msgchains usage tracking columns
|
||||
ALTER TABLE msgchains DROP COLUMN usage_cache_in;
|
||||
ALTER TABLE msgchains DROP COLUMN usage_cache_out;
|
||||
ALTER TABLE msgchains DROP COLUMN usage_cost_in;
|
||||
ALTER TABLE msgchains DROP COLUMN usage_cost_out;
|
||||
ALTER TABLE msgchains DROP COLUMN duration_seconds;
|
||||
|
||||
-- Drop toolcalls duration tracking column
|
||||
ALTER TABLE toolcalls DROP COLUMN duration_seconds;
|
||||
|
||||
-- Drop indexes
|
||||
DROP INDEX IF EXISTS flows_deleted_at_idx;
|
||||
DROP INDEX IF EXISTS msgchains_created_at_idx;
|
||||
DROP INDEX IF EXISTS msgchains_model_provider_idx;
|
||||
DROP INDEX IF EXISTS msgchains_model_idx;
|
||||
DROP INDEX IF EXISTS msgchains_model_provider_composite_idx;
|
||||
DROP INDEX IF EXISTS msgchains_created_at_flow_id_idx;
|
||||
DROP INDEX IF EXISTS msgchains_type_flow_id_idx;
|
||||
|
||||
-- Drop toolcalls analytics indexes
|
||||
DROP INDEX IF EXISTS toolcalls_created_at_idx;
|
||||
DROP INDEX IF EXISTS toolcalls_updated_at_idx;
|
||||
DROP INDEX IF EXISTS toolcalls_created_at_flow_id_idx;
|
||||
DROP INDEX IF EXISTS toolcalls_name_flow_id_idx;
|
||||
DROP INDEX IF EXISTS toolcalls_status_updated_at_idx;
|
||||
|
||||
-- Drop flows analytics indexes
|
||||
DROP INDEX IF EXISTS flows_created_at_idx;
|
||||
DROP INDEX IF EXISTS tasks_created_at_idx;
|
||||
DROP INDEX IF EXISTS subtasks_created_at_idx;
|
||||
DROP INDEX IF EXISTS tasks_flow_id_created_at_idx;
|
||||
DROP INDEX IF EXISTS subtasks_task_id_created_at_idx;
|
||||
|
||||
-- Drop usage privileges
|
||||
DELETE FROM privileges WHERE name IN ('usage.admin', 'usage.view');
|
||||
|
||||
-- Drop assistants analytics indexes
|
||||
DROP INDEX IF EXISTS assistants_deleted_at_idx;
|
||||
DROP INDEX IF EXISTS assistants_created_at_idx;
|
||||
DROP INDEX IF EXISTS assistants_flow_id_deleted_at_idx;
|
||||
DROP INDEX IF EXISTS assistants_flow_id_created_at_idx;
|
||||
|
||||
-- Drop additional analytics indexes
|
||||
DROP INDEX IF EXISTS subtasks_task_id_status_idx;
|
||||
DROP INDEX IF EXISTS toolcalls_flow_id_status_idx;
|
||||
DROP INDEX IF EXISTS msgchains_type_task_id_subtask_id_idx;
|
||||
DROP INDEX IF EXISTS tasks_flow_id_status_idx;
|
||||
DROP INDEX IF EXISTS subtasks_status_created_at_idx;
|
||||
DROP INDEX IF EXISTS toolcalls_name_status_idx;
|
||||
DROP INDEX IF EXISTS msgchains_type_created_at_idx;
|
||||
-- +goose StatementEnd
|
||||
@@ -0,0 +1,67 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
CREATE TYPE TOKEN_STATUS AS ENUM ('active', 'revoked');
|
||||
|
||||
CREATE TABLE api_tokens (
|
||||
id BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
token_id TEXT NOT NULL,
|
||||
user_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
role_id BIGINT NOT NULL REFERENCES roles(id),
|
||||
name TEXT NULL,
|
||||
ttl BIGINT NOT NULL,
|
||||
status TOKEN_STATUS NOT NULL DEFAULT 'active',
|
||||
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
||||
deleted_at TIMESTAMPTZ NULL,
|
||||
|
||||
CONSTRAINT api_tokens_token_id_unique UNIQUE (token_id)
|
||||
);
|
||||
|
||||
-- Partial unique index for name per user (only when name is not null and not deleted)
|
||||
CREATE UNIQUE INDEX api_tokens_name_user_unique_idx ON api_tokens(name, user_id)
|
||||
WHERE name IS NOT NULL AND deleted_at IS NULL;
|
||||
|
||||
CREATE INDEX api_tokens_token_id_idx ON api_tokens(token_id);
|
||||
CREATE INDEX api_tokens_user_id_idx ON api_tokens(user_id);
|
||||
CREATE INDEX api_tokens_status_idx ON api_tokens(status);
|
||||
CREATE INDEX api_tokens_deleted_at_idx ON api_tokens(deleted_at);
|
||||
|
||||
CREATE TRIGGER update_api_tokens_modified
|
||||
BEFORE UPDATE ON api_tokens
|
||||
FOR EACH ROW EXECUTE PROCEDURE update_modified_column();
|
||||
|
||||
-- Add privileges for Admin role (role_id = 1)
|
||||
INSERT INTO privileges (role_id, name) VALUES
|
||||
(1, 'settings.tokens.admin'),
|
||||
(1, 'settings.tokens.create'),
|
||||
(1, 'settings.tokens.view'),
|
||||
(1, 'settings.tokens.edit'),
|
||||
(1, 'settings.tokens.delete'),
|
||||
(1, 'settings.tokens.subscribe')
|
||||
ON CONFLICT DO NOTHING;
|
||||
|
||||
-- Add privileges for User role (role_id = 2)
|
||||
INSERT INTO privileges (role_id, name) VALUES
|
||||
(2, 'settings.tokens.create'),
|
||||
(2, 'settings.tokens.view'),
|
||||
(2, 'settings.tokens.edit'),
|
||||
(2, 'settings.tokens.delete'),
|
||||
(2, 'settings.tokens.subscribe')
|
||||
ON CONFLICT DO NOTHING;
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
DELETE FROM privileges WHERE name IN (
|
||||
'settings.tokens.create',
|
||||
'settings.tokens.view',
|
||||
'settings.tokens.edit',
|
||||
'settings.tokens.delete',
|
||||
'settings.tokens.admin',
|
||||
'settings.tokens.subscribe'
|
||||
);
|
||||
|
||||
DROP INDEX IF EXISTS api_tokens_name_user_unique_idx;
|
||||
DROP TABLE IF EXISTS api_tokens;
|
||||
DROP TYPE IF EXISTS TOKEN_STATUS;
|
||||
-- +goose StatementEnd
|
||||
@@ -0,0 +1,44 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
INSERT INTO privileges (role_id, name) VALUES
|
||||
(1, 'settings.user.admin'),
|
||||
(1, 'settings.user.view'),
|
||||
(1, 'settings.user.edit'),
|
||||
(1, 'settings.user.subscribe'),
|
||||
(2, 'settings.user.view'),
|
||||
(2, 'settings.user.edit'),
|
||||
(2, 'settings.user.subscribe');
|
||||
|
||||
CREATE TABLE user_preferences (
|
||||
id BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
user_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
preferences JSONB NOT NULL DEFAULT '{"favoriteFlows": []}'::JSONB,
|
||||
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT user_preferences_user_id_unique UNIQUE (user_id)
|
||||
);
|
||||
|
||||
CREATE INDEX user_preferences_user_id_idx ON user_preferences(user_id);
|
||||
CREATE INDEX user_preferences_preferences_idx ON user_preferences USING GIN (preferences);
|
||||
|
||||
INSERT INTO user_preferences (user_id, preferences)
|
||||
SELECT id, '{"favoriteFlows": []}'::JSONB FROM users
|
||||
ON CONFLICT DO NOTHING;
|
||||
|
||||
CREATE OR REPLACE TRIGGER update_user_preferences_modified
|
||||
BEFORE UPDATE ON user_preferences
|
||||
FOR EACH ROW EXECUTE PROCEDURE update_modified_column();
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
DROP TABLE user_preferences;
|
||||
|
||||
DELETE FROM privileges WHERE name IN (
|
||||
'settings.user.admin',
|
||||
'settings.user.view',
|
||||
'settings.user.edit',
|
||||
'settings.user.subscribe'
|
||||
);
|
||||
-- +goose StatementEnd
|
||||
@@ -0,0 +1,52 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
-- Add sploitus to the searchengine_type enum
|
||||
CREATE TYPE SEARCHENGINE_TYPE_NEW AS ENUM (
|
||||
'google',
|
||||
'tavily',
|
||||
'traversaal',
|
||||
'browser',
|
||||
'duckduckgo',
|
||||
'perplexity',
|
||||
'searxng',
|
||||
'sploitus'
|
||||
);
|
||||
|
||||
-- Update the searchlogs table to use the new enum type
|
||||
ALTER TABLE searchlogs
|
||||
ALTER COLUMN engine TYPE SEARCHENGINE_TYPE_NEW USING engine::text::SEARCHENGINE_TYPE_NEW;
|
||||
|
||||
-- Drop the old type and rename the new one
|
||||
DROP TYPE SEARCHENGINE_TYPE;
|
||||
ALTER TYPE SEARCHENGINE_TYPE_NEW RENAME TO SEARCHENGINE_TYPE;
|
||||
|
||||
-- Ensure NOT NULL constraint is preserved
|
||||
ALTER TABLE searchlogs
|
||||
ALTER COLUMN engine SET NOT NULL;
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
-- Revert the changes by removing sploitus from the enum
|
||||
CREATE TYPE SEARCHENGINE_TYPE_NEW AS ENUM (
|
||||
'google',
|
||||
'tavily',
|
||||
'traversaal',
|
||||
'browser',
|
||||
'duckduckgo',
|
||||
'perplexity',
|
||||
'searxng'
|
||||
);
|
||||
|
||||
-- Update the searchlogs table to use the reverted enum type
|
||||
ALTER TABLE searchlogs
|
||||
ALTER COLUMN engine TYPE SEARCHENGINE_TYPE_NEW USING engine::text::SEARCHENGINE_TYPE_NEW;
|
||||
|
||||
-- Drop the new type and rename the reverted one
|
||||
DROP TYPE SEARCHENGINE_TYPE;
|
||||
ALTER TYPE SEARCHENGINE_TYPE_NEW RENAME TO SEARCHENGINE_TYPE;
|
||||
|
||||
-- Ensure NOT NULL constraint is preserved
|
||||
ALTER TABLE searchlogs
|
||||
ALTER COLUMN engine SET NOT NULL;
|
||||
-- +goose StatementEnd
|
||||
@@ -0,0 +1,82 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
-- Add Chinese AI providers to the provider_type enum
|
||||
CREATE TYPE PROVIDER_TYPE_NEW AS ENUM (
|
||||
'openai',
|
||||
'anthropic',
|
||||
'gemini',
|
||||
'bedrock',
|
||||
'ollama',
|
||||
'custom',
|
||||
'deepseek',
|
||||
'glm',
|
||||
'kimi',
|
||||
'qwen'
|
||||
);
|
||||
|
||||
-- Update columns to use the new enum type
|
||||
ALTER TABLE providers
|
||||
ALTER COLUMN type TYPE PROVIDER_TYPE_NEW USING type::text::PROVIDER_TYPE_NEW;
|
||||
|
||||
ALTER TABLE flows
|
||||
ALTER COLUMN model_provider_type TYPE PROVIDER_TYPE_NEW USING model_provider_type::text::PROVIDER_TYPE_NEW;
|
||||
|
||||
ALTER TABLE assistants
|
||||
ALTER COLUMN model_provider_type TYPE PROVIDER_TYPE_NEW USING model_provider_type::text::PROVIDER_TYPE_NEW;
|
||||
|
||||
-- Drop the old type and rename the new one
|
||||
DROP TYPE PROVIDER_TYPE;
|
||||
ALTER TYPE PROVIDER_TYPE_NEW RENAME TO PROVIDER_TYPE;
|
||||
|
||||
-- Ensure NOT NULL constraints are preserved
|
||||
ALTER TABLE providers
|
||||
ALTER COLUMN type SET NOT NULL;
|
||||
|
||||
ALTER TABLE flows
|
||||
ALTER COLUMN model_provider_type SET NOT NULL;
|
||||
|
||||
ALTER TABLE assistants
|
||||
ALTER COLUMN model_provider_type SET NOT NULL;
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
-- Delete providers using new types before reverting the enum
|
||||
DELETE FROM providers WHERE type IN ('deepseek', 'glm', 'kimi', 'qwen');
|
||||
DELETE FROM flows WHERE model_provider_type IN ('deepseek', 'glm', 'kimi', 'qwen');
|
||||
DELETE FROM assistants WHERE model_provider_type IN ('deepseek', 'glm', 'kimi', 'qwen');
|
||||
|
||||
-- Create new enum type without the Chinese AI providers
|
||||
CREATE TYPE PROVIDER_TYPE_NEW AS ENUM (
|
||||
'openai',
|
||||
'anthropic',
|
||||
'gemini',
|
||||
'bedrock',
|
||||
'ollama',
|
||||
'custom'
|
||||
);
|
||||
|
||||
-- Update columns to use the new enum type
|
||||
ALTER TABLE providers
|
||||
ALTER COLUMN type TYPE PROVIDER_TYPE_NEW USING type::text::PROVIDER_TYPE_NEW;
|
||||
|
||||
ALTER TABLE flows
|
||||
ALTER COLUMN model_provider_type TYPE PROVIDER_TYPE_NEW USING model_provider_type::text::PROVIDER_TYPE_NEW;
|
||||
|
||||
ALTER TABLE assistants
|
||||
ALTER COLUMN model_provider_type TYPE PROVIDER_TYPE_NEW USING model_provider_type::text::PROVIDER_TYPE_NEW;
|
||||
|
||||
-- Drop the old type and rename the new one
|
||||
DROP TYPE PROVIDER_TYPE;
|
||||
ALTER TYPE PROVIDER_TYPE_NEW RENAME TO PROVIDER_TYPE;
|
||||
|
||||
-- Ensure NOT NULL constraints are preserved
|
||||
ALTER TABLE providers
|
||||
ALTER COLUMN type SET NOT NULL;
|
||||
|
||||
ALTER TABLE flows
|
||||
ALTER COLUMN model_provider_type SET NOT NULL;
|
||||
|
||||
ALTER TABLE assistants
|
||||
ALTER COLUMN model_provider_type SET NOT NULL;
|
||||
-- +goose StatementEnd
|
||||
@@ -0,0 +1,114 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
|
||||
-- Add new prompt types for agent supervision
|
||||
CREATE TYPE PROMPT_TYPE_NEW AS ENUM (
|
||||
'primary_agent',
|
||||
'assistant',
|
||||
'pentester',
|
||||
'question_pentester',
|
||||
'coder',
|
||||
'question_coder',
|
||||
'installer',
|
||||
'question_installer',
|
||||
'searcher',
|
||||
'question_searcher',
|
||||
'memorist',
|
||||
'question_memorist',
|
||||
'adviser',
|
||||
'question_adviser',
|
||||
'generator',
|
||||
'subtasks_generator',
|
||||
'refiner',
|
||||
'subtasks_refiner',
|
||||
'reporter',
|
||||
'task_reporter',
|
||||
'reflector',
|
||||
'question_reflector',
|
||||
'enricher',
|
||||
'question_enricher',
|
||||
'toolcall_fixer',
|
||||
'input_toolcall_fixer',
|
||||
'summarizer',
|
||||
'image_chooser',
|
||||
'language_chooser',
|
||||
'flow_descriptor',
|
||||
'task_descriptor',
|
||||
'execution_logs',
|
||||
'full_execution_context',
|
||||
'short_execution_context',
|
||||
'tool_call_id_collector',
|
||||
'tool_call_id_detector',
|
||||
'question_execution_monitor',
|
||||
'question_task_planner',
|
||||
'task_assignment_wrapper'
|
||||
);
|
||||
|
||||
-- Update the searchlogs table to use the new enum type
|
||||
ALTER TABLE prompts
|
||||
ALTER COLUMN type TYPE PROMPT_TYPE_NEW USING type::text::PROMPT_TYPE_NEW;
|
||||
|
||||
-- Drop the old type and rename the new one
|
||||
DROP TYPE PROMPT_TYPE;
|
||||
ALTER TYPE PROMPT_TYPE_NEW RENAME TO PROMPT_TYPE;
|
||||
|
||||
-- Set the column as NOT NULL
|
||||
ALTER TABLE prompts
|
||||
ALTER COLUMN type SET NOT NULL;
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
|
||||
-- Revert the changes by removing agent supervision prompt types from the enum
|
||||
CREATE TYPE PROMPT_TYPE_NEW AS ENUM (
|
||||
'primary_agent',
|
||||
'assistant',
|
||||
'pentester',
|
||||
'question_pentester',
|
||||
'coder',
|
||||
'question_coder',
|
||||
'installer',
|
||||
'question_installer',
|
||||
'searcher',
|
||||
'question_searcher',
|
||||
'memorist',
|
||||
'question_memorist',
|
||||
'adviser',
|
||||
'question_adviser',
|
||||
'generator',
|
||||
'subtasks_generator',
|
||||
'refiner',
|
||||
'subtasks_refiner',
|
||||
'reporter',
|
||||
'task_reporter',
|
||||
'reflector',
|
||||
'question_reflector',
|
||||
'enricher',
|
||||
'question_enricher',
|
||||
'toolcall_fixer',
|
||||
'input_toolcall_fixer',
|
||||
'summarizer',
|
||||
'image_chooser',
|
||||
'language_chooser',
|
||||
'flow_descriptor',
|
||||
'task_descriptor',
|
||||
'execution_logs',
|
||||
'full_execution_context',
|
||||
'short_execution_context',
|
||||
'tool_call_id_collector',
|
||||
'tool_call_id_detector'
|
||||
);
|
||||
|
||||
-- Update the prompts table to use the new enum type
|
||||
ALTER TABLE prompts
|
||||
ALTER COLUMN type TYPE PROMPT_TYPE_NEW USING type::text::PROMPT_TYPE_NEW;
|
||||
|
||||
-- Drop the old type and rename the new one
|
||||
DROP TYPE PROMPT_TYPE;
|
||||
ALTER TYPE PROMPT_TYPE_NEW RENAME TO PROMPT_TYPE;
|
||||
|
||||
-- Set the column as NOT NULL
|
||||
ALTER TABLE prompts
|
||||
ALTER COLUMN type SET NOT NULL;
|
||||
-- +goose StatementEnd
|
||||
@@ -0,0 +1,49 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
INSERT INTO privileges (role_id, name) VALUES
|
||||
(1, 'templates.admin'),
|
||||
(1, 'templates.create'),
|
||||
(1, 'templates.view'),
|
||||
(1, 'templates.edit'),
|
||||
(1, 'templates.delete'),
|
||||
(1, 'templates.subscribe'),
|
||||
(2, 'templates.create'),
|
||||
(2, 'templates.view'),
|
||||
(2, 'templates.edit'),
|
||||
(2, 'templates.delete'),
|
||||
(2, 'templates.subscribe')
|
||||
ON CONFLICT DO NOTHING;
|
||||
|
||||
CREATE TABLE flow_templates (
|
||||
id BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
user_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
title TEXT NOT NULL,
|
||||
text TEXT NOT NULL,
|
||||
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT flow_templates_title_not_empty CHECK (length(trim(title)) > 0),
|
||||
CONSTRAINT flow_templates_text_not_empty CHECK (length(trim(text)) > 0)
|
||||
);
|
||||
|
||||
CREATE INDEX flow_templates_user_id_idx ON flow_templates(user_id);
|
||||
CREATE INDEX flow_templates_created_at_idx ON flow_templates(created_at DESC);
|
||||
|
||||
CREATE OR REPLACE TRIGGER update_flow_templates_modified
|
||||
BEFORE UPDATE ON flow_templates
|
||||
FOR EACH ROW EXECUTE PROCEDURE update_modified_column();
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
DROP TABLE IF EXISTS flow_templates;
|
||||
|
||||
DELETE FROM privileges WHERE name IN (
|
||||
'templates.admin',
|
||||
'templates.create',
|
||||
'templates.view',
|
||||
'templates.edit',
|
||||
'templates.delete',
|
||||
'templates.subscribe'
|
||||
);
|
||||
-- +goose StatementEnd
|
||||
@@ -0,0 +1,85 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
INSERT INTO privileges (role_id, name) VALUES
|
||||
(1, 'flow_files.admin'),
|
||||
(1, 'flow_files.view'),
|
||||
(1, 'flow_files.upload'),
|
||||
(1, 'flow_files.edit'),
|
||||
(1, 'flow_files.delete'),
|
||||
(1, 'flow_files.download'),
|
||||
(1, 'flow_files.subscribe'),
|
||||
(2, 'flow_files.view'),
|
||||
(2, 'flow_files.upload'),
|
||||
(2, 'flow_files.edit'),
|
||||
(2, 'flow_files.delete'),
|
||||
(2, 'flow_files.download'),
|
||||
(2, 'flow_files.subscribe')
|
||||
ON CONFLICT DO NOTHING;
|
||||
|
||||
INSERT INTO privileges (role_id, name) VALUES
|
||||
(1, 'resources.admin'),
|
||||
(1, 'resources.view'),
|
||||
(1, 'resources.upload'),
|
||||
(1, 'resources.edit'),
|
||||
(1, 'resources.delete'),
|
||||
(1, 'resources.download'),
|
||||
(1, 'resources.subscribe'),
|
||||
(2, 'resources.view'),
|
||||
(2, 'resources.upload'),
|
||||
(2, 'resources.edit'),
|
||||
(2, 'resources.delete'),
|
||||
(2, 'resources.download'),
|
||||
(2, 'resources.subscribe')
|
||||
ON CONFLICT DO NOTHING;
|
||||
|
||||
CREATE TABLE user_resources (
|
||||
id BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
user_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
hash TEXT NOT NULL DEFAULT '',
|
||||
name TEXT NOT NULL,
|
||||
path TEXT NOT NULL,
|
||||
size BIGINT NOT NULL DEFAULT 0,
|
||||
is_dir BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT user_resources_user_path_unique UNIQUE (user_id, path),
|
||||
CONSTRAINT user_resources_name_not_empty CHECK (length(trim(name)) > 0),
|
||||
CONSTRAINT user_resources_path_not_empty CHECK (length(trim(path)) > 0)
|
||||
);
|
||||
|
||||
CREATE INDEX user_resources_user_id_idx ON user_resources(user_id);
|
||||
CREATE INDEX user_resources_hash_idx ON user_resources(hash) WHERE hash != '';
|
||||
CREATE INDEX user_resources_path_idx ON user_resources USING btree (path text_pattern_ops);
|
||||
CREATE INDEX user_resources_user_path_idx ON user_resources(user_id, path text_pattern_ops);
|
||||
CREATE INDEX user_resources_updated_at_idx ON user_resources(updated_at DESC);
|
||||
|
||||
CREATE OR REPLACE TRIGGER update_user_resources_modified
|
||||
BEFORE UPDATE ON user_resources
|
||||
FOR EACH ROW EXECUTE PROCEDURE update_modified_column();
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
DROP TABLE IF EXISTS user_resources;
|
||||
|
||||
DELETE FROM privileges WHERE name IN (
|
||||
'flow_files.admin',
|
||||
'flow_files.view',
|
||||
'flow_files.upload',
|
||||
'flow_files.edit',
|
||||
'flow_files.delete',
|
||||
'flow_files.download',
|
||||
'flow_files.subscribe'
|
||||
);
|
||||
|
||||
DELETE FROM privileges WHERE name IN (
|
||||
'resources.admin',
|
||||
'resources.view',
|
||||
'resources.upload',
|
||||
'resources.edit',
|
||||
'resources.delete',
|
||||
'resources.download',
|
||||
'resources.subscribe'
|
||||
);
|
||||
-- +goose StatementEnd
|
||||
@@ -0,0 +1,108 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
|
||||
INSERT INTO privileges (role_id, name) VALUES
|
||||
(1, 'knowledge.admin'),
|
||||
(1, 'knowledge.view'),
|
||||
(1, 'knowledge.create'),
|
||||
(1, 'knowledge.edit'),
|
||||
(1, 'knowledge.delete'),
|
||||
(1, 'knowledge.search'),
|
||||
(1, 'knowledge.subscribe'),
|
||||
(2, 'knowledge.view'),
|
||||
(2, 'knowledge.create'),
|
||||
(2, 'knowledge.edit'),
|
||||
(2, 'knowledge.delete'),
|
||||
(2, 'knowledge.search'),
|
||||
(2, 'knowledge.subscribe')
|
||||
ON CONFLICT DO NOTHING;
|
||||
|
||||
-- Ensure the vector extension is present (langchaingo also creates it, but migrations
|
||||
-- run before any flow starts, so we need it here for the backfill UPDATE below).
|
||||
CREATE EXTENSION IF NOT EXISTS vector;
|
||||
|
||||
-- Logical namespace for embeddings.
|
||||
-- DDL kept identical to what langchaingo's createCollectionTableIfNotExists generates
|
||||
-- so IF NOT EXISTS is a true no-op when the table already exists.
|
||||
CREATE TABLE IF NOT EXISTS langchain_pg_collection (
|
||||
name varchar,
|
||||
cmetadata json,
|
||||
"uuid" uuid NOT NULL,
|
||||
UNIQUE (name),
|
||||
PRIMARY KEY ("uuid")
|
||||
);
|
||||
|
||||
-- Physical storage for chunked text, vector embeddings and per-document metadata.
|
||||
-- DDL kept identical to what langchaingo's createEmbeddingTableIfNotExists generates.
|
||||
CREATE TABLE IF NOT EXISTS langchain_pg_embedding (
|
||||
collection_id uuid,
|
||||
embedding vector,
|
||||
document varchar,
|
||||
cmetadata json,
|
||||
"uuid" uuid NOT NULL,
|
||||
CONSTRAINT langchain_pg_embedding_collection_id_fkey
|
||||
FOREIGN KEY (collection_id)
|
||||
REFERENCES langchain_pg_collection ("uuid") ON DELETE CASCADE,
|
||||
PRIMARY KEY ("uuid")
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS langchain_pg_embedding_collection_id
|
||||
ON langchain_pg_embedding (collection_id);
|
||||
|
||||
-- Step 1: Backfill user_id from flows for documents whose flow still exists.
|
||||
-- Documents whose flow_id has no matching row are left with user_id NULL.
|
||||
UPDATE langchain_pg_embedding e
|
||||
SET cmetadata = (e.cmetadata::jsonb || jsonb_build_object('user_id', f.user_id))::json
|
||||
FROM langchain_pg_collection c, flows f
|
||||
WHERE e.collection_id = c.uuid
|
||||
AND c.name = 'langchain'
|
||||
AND (e.cmetadata ->> 'flow_id') IS NOT NULL
|
||||
AND (e.cmetadata ->> 'user_id') IS NULL
|
||||
AND f.id = (e.cmetadata ->> 'flow_id')::bigint;
|
||||
|
||||
-- Step 2: For any remaining documents still missing user_id (no flow_id, deleted
|
||||
-- flow, or manually created before user tracking), default to user_id = 1.
|
||||
UPDATE langchain_pg_embedding e
|
||||
SET cmetadata = (e.cmetadata::jsonb || jsonb_build_object('user_id', 1))::json
|
||||
FROM langchain_pg_collection c
|
||||
WHERE e.collection_id = c.uuid
|
||||
AND c.name = 'langchain'
|
||||
AND (e.cmetadata ->> 'user_id') IS NULL;
|
||||
|
||||
-- Purge accumulated memory documents from the vector store that belong to flows
|
||||
-- which have already been soft-deleted (deleted_at IS NOT NULL) or no longer exist
|
||||
-- in the flows table at all.
|
||||
--
|
||||
-- These documents are never queried again after their flow is gone, so keeping them
|
||||
-- only wastes storage and degrades vector search performance.
|
||||
--
|
||||
-- The flows table uses soft deletes:
|
||||
-- UPDATE flows SET deleted_at = CURRENT_TIMESTAMP WHERE id = $1
|
||||
-- so the condition covers both hard-missing rows and soft-deleted ones.
|
||||
DELETE FROM langchain_pg_embedding e
|
||||
USING langchain_pg_collection c
|
||||
WHERE e.collection_id = c.uuid
|
||||
AND c.name = 'langchain'
|
||||
AND COALESCE(e.cmetadata ->> 'doc_type', '') = 'memory'
|
||||
AND (e.cmetadata ->> 'flow_id') IS NOT NULL
|
||||
AND NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM flows f
|
||||
WHERE f.id = (e.cmetadata ->> 'flow_id')::bigint
|
||||
AND f.deleted_at IS NULL
|
||||
);
|
||||
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
|
||||
DELETE FROM privileges WHERE name LIKE 'knowledge.%';
|
||||
|
||||
-- The langchain tables are intentionally NOT dropped in Down:
|
||||
-- they hold production knowledge data managed by the pgvector store.
|
||||
|
||||
-- The deleted memory documents cannot be recovered (the embedding data is gone).
|
||||
-- Down migration is intentionally a no-op.
|
||||
|
||||
-- +goose StatementEnd
|
||||
@@ -0,0 +1,16 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
|
||||
INSERT INTO privileges (role_id, name) VALUES
|
||||
(1, 'anonymize.call'),
|
||||
(2, 'anonymize.call')
|
||||
ON CONFLICT DO NOTHING;
|
||||
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
|
||||
DELETE FROM privileges WHERE name = 'anonymize.call';
|
||||
|
||||
-- +goose StatementEnd
|
||||
@@ -0,0 +1,17 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
|
||||
INSERT INTO privileges (role_id, name) VALUES
|
||||
(1, 'toolcalls.admin'),
|
||||
(1, 'toolcalls.view'),
|
||||
(2, 'toolcalls.view')
|
||||
ON CONFLICT DO NOTHING;
|
||||
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
|
||||
DELETE FROM privileges WHERE name IN ('toolcalls.admin', 'toolcalls.view');
|
||||
|
||||
-- +goose StatementEnd
|
||||
Reference in New Issue
Block a user