mirror of
https://github.com/n8n-io/n8n.git
synced 2026-10-19 16:55:02 +02:00
feat(core): Add skill Assistant availability column (no-changelog)
This commit is contained in:
parent
d74f3f2cdd
commit
fc048fb7b6
3
docs/generated/postgres-schema/README.md
generated
3
docs/generated/postgres-schema/README.md
generated
|
|
@ -135,7 +135,7 @@ Auto-generated from the PostgreSQL migrations in @n8n/db. Do not edit by hand.
|
|||
| [public.settings](public.settings.md) | 3 | | BASE TABLE |
|
||||
| [public.shared_credentials](public.shared_credentials.md) | 5 | | BASE TABLE |
|
||||
| [public.shared_workflow](public.shared_workflow.md) | 5 | | BASE TABLE |
|
||||
| [public.skill](public.skill.md) | 7 | | BASE TABLE |
|
||||
| [public.skill](public.skill.md) | 8 | | BASE TABLE |
|
||||
| [public.skill_file](public.skill_file.md) | 5 | | BASE TABLE |
|
||||
| [public.skill_version](public.skill_version.md) | 11 | | BASE TABLE |
|
||||
| [public.tag_entity](public.tag_entity.md) | 4 | | BASE TABLE |
|
||||
|
|
@ -1713,6 +1713,7 @@ erDiagram
|
|||
}
|
||||
"public.skill" {
|
||||
varchar_36_ agentId FK
|
||||
boolean availableToAssistant
|
||||
timestamp_3__with_time_zone createdAt
|
||||
uuid createdById FK
|
||||
varchar_36_ id
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ erDiagram
|
|||
}
|
||||
"public.skill" {
|
||||
varchar_36_ agentId FK
|
||||
boolean availableToAssistant
|
||||
timestamp_3__with_time_zone createdAt
|
||||
uuid createdById FK
|
||||
varchar_36_ id
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ erDiagram
|
|||
}
|
||||
"public.skill" {
|
||||
varchar_36_ agentId FK
|
||||
boolean availableToAssistant
|
||||
timestamp_3__with_time_zone createdAt
|
||||
uuid createdById FK
|
||||
varchar_36_ id
|
||||
|
|
|
|||
1
docs/generated/postgres-schema/public.agents.md
generated
1
docs/generated/postgres-schema/public.agents.md
generated
|
|
@ -334,6 +334,7 @@ erDiagram
|
|||
}
|
||||
"public.skill" {
|
||||
varchar_36_ agentId FK
|
||||
boolean availableToAssistant
|
||||
timestamp_3__with_time_zone createdAt
|
||||
uuid createdById FK
|
||||
varchar_36_ id
|
||||
|
|
|
|||
1
docs/generated/postgres-schema/public.project.md
generated
1
docs/generated/postgres-schema/public.project.md
generated
|
|
@ -259,6 +259,7 @@ erDiagram
|
|||
}
|
||||
"public.skill" {
|
||||
varchar_36_ agentId FK
|
||||
boolean availableToAssistant
|
||||
timestamp_3__with_time_zone createdAt
|
||||
uuid createdById FK
|
||||
varchar_36_ id
|
||||
|
|
|
|||
3
docs/generated/postgres-schema/public.skill.md
generated
3
docs/generated/postgres-schema/public.skill.md
generated
|
|
@ -5,6 +5,7 @@
|
|||
| Name | Type | Default | Nullable | Children | Parents | Comment |
|
||||
| ---- | ---- | ------- | -------- | -------- | ------- | ------- |
|
||||
| agentId | varchar(36) | | true | | [public.agents](public.agents.md) | Set when only this agent can use the skill. projectId is then NULL: the agent holds the project |
|
||||
| availableToAssistant | boolean | false | false | | | |
|
||||
| createdAt | timestamp(3) with time zone | CURRENT_TIMESTAMP(3) | false | | | |
|
||||
| createdById | uuid | | true | | [public.user](public.user.md) | Author. NULL after the author is deleted |
|
||||
| id | varchar(36) | | false | [public.agent_skill_dependency](public.agent_skill_dependency.md) [public.agent_version_skill_dependency](public.agent_version_skill_dependency.md) [public.skill_version](public.skill_version.md) | | skill_\<nanoid\>, the same format agents use |
|
||||
|
|
@ -21,6 +22,7 @@
|
|||
| FK_4de4501583cd1fcd6f5ea85f547 | FOREIGN KEY | FOREIGN KEY ("createdById") REFERENCES "user"(id) ON DELETE SET NULL |
|
||||
| FK_7d4fb6af107e507d9a86293cf9d | FOREIGN KEY | FOREIGN KEY ("agentId") REFERENCES agents(id) ON DELETE CASCADE |
|
||||
| PK_a0d33334424e64fb78dc3ce7196 | PRIMARY KEY | PRIMARY KEY (id) |
|
||||
| skill_availableToAssistant_not_null | n | NOT NULL "availableToAssistant" |
|
||||
| skill_createdAt_not_null | n | NOT NULL "createdAt" |
|
||||
| skill_id_not_null | n | NOT NULL id |
|
||||
| skill_source_not_null | n | NOT NULL source |
|
||||
|
|
@ -48,6 +50,7 @@ erDiagram
|
|||
|
||||
"public.skill" {
|
||||
varchar_36_ agentId FK
|
||||
boolean availableToAssistant
|
||||
timestamp_3__with_time_zone createdAt
|
||||
uuid createdById FK
|
||||
varchar_36_ id
|
||||
|
|
|
|||
|
|
@ -104,6 +104,7 @@ erDiagram
|
|||
}
|
||||
"public.skill" {
|
||||
varchar_36_ agentId FK
|
||||
boolean availableToAssistant
|
||||
timestamp_3__with_time_zone createdAt
|
||||
uuid createdById FK
|
||||
varchar_36_ id
|
||||
|
|
|
|||
1
docs/generated/postgres-schema/public.user.md
generated
1
docs/generated/postgres-schema/public.user.md
generated
|
|
@ -427,6 +427,7 @@ erDiagram
|
|||
}
|
||||
"public.skill" {
|
||||
varchar_36_ agentId FK
|
||||
boolean availableToAssistant
|
||||
timestamp_3__with_time_zone createdAt
|
||||
uuid createdById FK
|
||||
varchar_36_ id
|
||||
|
|
|
|||
3
docs/generated/sqlite-schema/README.md
generated
3
docs/generated/sqlite-schema/README.md
generated
|
|
@ -135,7 +135,7 @@ Auto-generated from the SQLite migrations in @n8n/db. Do not edit by hand.
|
|||
| [settings](settings.md) | 3 | | table |
|
||||
| [shared_credentials](shared_credentials.md) | 5 | | table |
|
||||
| [shared_workflow](shared_workflow.md) | 5 | | table |
|
||||
| [skill](skill.md) | 7 | | table |
|
||||
| [skill](skill.md) | 8 | | table |
|
||||
| [skill_file](skill_file.md) | 5 | | table |
|
||||
| [skill_version](skill_version.md) | 11 | | table |
|
||||
| [tag_entity](tag_entity.md) | 4 | | table |
|
||||
|
|
@ -1699,6 +1699,7 @@ erDiagram
|
|||
}
|
||||
"skill" {
|
||||
varchar_36_ agentId FK
|
||||
boolean availableToAssistant
|
||||
datetime_3_ createdAt
|
||||
varchar createdById FK
|
||||
varchar_36_ id PK
|
||||
|
|
|
|||
|
|
@ -72,6 +72,7 @@ erDiagram
|
|||
}
|
||||
"skill" {
|
||||
varchar_36_ agentId FK
|
||||
boolean availableToAssistant
|
||||
datetime_3_ createdAt
|
||||
varchar createdById FK
|
||||
varchar_36_ id PK
|
||||
|
|
|
|||
|
|
@ -67,6 +67,7 @@ erDiagram
|
|||
}
|
||||
"skill" {
|
||||
varchar_36_ agentId FK
|
||||
boolean availableToAssistant
|
||||
datetime_3_ createdAt
|
||||
varchar createdById FK
|
||||
varchar_36_ id PK
|
||||
|
|
|
|||
1
docs/generated/sqlite-schema/agents.md
generated
1
docs/generated/sqlite-schema/agents.md
generated
|
|
@ -336,6 +336,7 @@ erDiagram
|
|||
}
|
||||
"skill" {
|
||||
varchar_36_ agentId FK
|
||||
boolean availableToAssistant
|
||||
datetime_3_ createdAt
|
||||
varchar createdById FK
|
||||
varchar_36_ id PK
|
||||
|
|
|
|||
1
docs/generated/sqlite-schema/project.md
generated
1
docs/generated/sqlite-schema/project.md
generated
|
|
@ -265,6 +265,7 @@ erDiagram
|
|||
}
|
||||
"skill" {
|
||||
varchar_36_ agentId FK
|
||||
boolean availableToAssistant
|
||||
datetime_3_ createdAt
|
||||
varchar createdById FK
|
||||
varchar_36_ id PK
|
||||
|
|
|
|||
4
docs/generated/sqlite-schema/skill.md
generated
4
docs/generated/sqlite-schema/skill.md
generated
|
|
@ -6,7 +6,7 @@
|
|||
<summary><strong>Table Definition</strong></summary>
|
||||
|
||||
```sql
|
||||
CREATE TABLE "skill" ("id" varchar(36) PRIMARY KEY NOT NULL, "projectId" varchar(36), "agentId" varchar(36), "source" varchar(16) NOT NULL, "createdById" varchar, "createdAt" datetime(3) NOT NULL DEFAULT (STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW')), "updatedAt" datetime(3) NOT NULL DEFAULT (STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW')), CONSTRAINT "CHK_skill_single_target" CHECK ("agentId" IS NULL OR "projectId" IS NULL), CONSTRAINT "FK_402ed37bff0d3134f6e782455ed" FOREIGN KEY ("projectId") REFERENCES "project" ("id") ON DELETE CASCADE, CONSTRAINT "FK_7d4fb6af107e507d9a86293cf9d" FOREIGN KEY ("agentId") REFERENCES "agents" ("id") ON DELETE CASCADE, CONSTRAINT "FK_4de4501583cd1fcd6f5ea85f547" FOREIGN KEY ("createdById") REFERENCES "user" ("id") ON DELETE SET NULL)
|
||||
CREATE TABLE "skill" ("id" varchar(36) PRIMARY KEY NOT NULL, "projectId" varchar(36), "agentId" varchar(36), "source" varchar(16) NOT NULL, "createdById" varchar, "createdAt" datetime(3) NOT NULL DEFAULT (STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW')), "updatedAt" datetime(3) NOT NULL DEFAULT (STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW')), "availableToAssistant" boolean NOT NULL DEFAULT false, CONSTRAINT "CHK_skill_single_target" CHECK ("agentId" IS NULL OR "projectId" IS NULL), CONSTRAINT "FK_402ed37bff0d3134f6e782455ed" FOREIGN KEY ("projectId") REFERENCES "project" ("id") ON DELETE CASCADE, CONSTRAINT "FK_7d4fb6af107e507d9a86293cf9d" FOREIGN KEY ("agentId") REFERENCES "agents" ("id") ON DELETE CASCADE, CONSTRAINT "FK_4de4501583cd1fcd6f5ea85f547" FOREIGN KEY ("createdById") REFERENCES "user" ("id") ON DELETE SET NULL)
|
||||
```
|
||||
|
||||
</details>
|
||||
|
|
@ -16,6 +16,7 @@ CREATE TABLE "skill" ("id" varchar(36) PRIMARY KEY NOT NULL, "projectId" varchar
|
|||
| Name | Type | Default | Nullable | Children | Parents | Comment |
|
||||
| ---- | ---- | ------- | -------- | -------- | ------- | ------- |
|
||||
| agentId | varchar(36) | | true | | [agents](agents.md) | |
|
||||
| availableToAssistant | boolean | false | false | | | |
|
||||
| createdAt | datetime(3) | STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW') | false | | | |
|
||||
| createdById | varchar | | true | | [user](user.md) | |
|
||||
| id | varchar(36) | | false | [agent_skill_dependency](agent_skill_dependency.md) [agent_version_skill_dependency](agent_version_skill_dependency.md) [skill_version](skill_version.md) | | |
|
||||
|
|
@ -56,6 +57,7 @@ erDiagram
|
|||
|
||||
"skill" {
|
||||
varchar_36_ agentId FK
|
||||
boolean availableToAssistant
|
||||
datetime_3_ createdAt
|
||||
varchar createdById FK
|
||||
varchar_36_ id PK
|
||||
|
|
|
|||
1
docs/generated/sqlite-schema/skill_version.md
generated
1
docs/generated/sqlite-schema/skill_version.md
generated
|
|
@ -107,6 +107,7 @@ erDiagram
|
|||
}
|
||||
"skill" {
|
||||
varchar_36_ agentId FK
|
||||
boolean availableToAssistant
|
||||
datetime_3_ createdAt
|
||||
varchar createdById FK
|
||||
varchar_36_ id PK
|
||||
|
|
|
|||
1
docs/generated/sqlite-schema/user.md
generated
1
docs/generated/sqlite-schema/user.md
generated
|
|
@ -433,6 +433,7 @@ erDiagram
|
|||
}
|
||||
"skill" {
|
||||
varchar_36_ agentId FK
|
||||
boolean availableToAssistant
|
||||
datetime_3_ createdAt
|
||||
varchar createdById FK
|
||||
varchar_36_ id PK
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
import type { MigrationContext, ReversibleMigration } from '../migration-types';
|
||||
|
||||
export class AddSkillAssistantAvailability1792418677997 implements ReversibleMigration {
|
||||
async up({ runQuery, escape }: MigrationContext) {
|
||||
// ALTER preserves the skill versions and references on SQLite.
|
||||
await runQuery(
|
||||
`ALTER TABLE ${escape.tableName('skill')} ADD COLUMN ${escape.columnName('availableToAssistant')} boolean NOT NULL DEFAULT false`,
|
||||
);
|
||||
}
|
||||
|
||||
async down({ runQuery, escape }: MigrationContext) {
|
||||
await runQuery(
|
||||
`ALTER TABLE ${escape.tableName('skill')} DROP COLUMN ${escape.columnName('availableToAssistant')}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -23,6 +23,9 @@ export class Skill extends WithTimestamps {
|
|||
@Column({ type: 'varchar', length: 36, nullable: true })
|
||||
agentId: string | null;
|
||||
|
||||
@Column({ type: 'boolean', default: false })
|
||||
availableToAssistant: boolean;
|
||||
|
||||
@Column({ type: 'varchar', length: 16 })
|
||||
source: SkillSource;
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,71 @@
|
|||
import {
|
||||
createTestMigrationContext,
|
||||
initDbUpToMigration,
|
||||
runSingleMigration,
|
||||
type TestMigrationContext,
|
||||
} from '@n8n/backend-test-utils';
|
||||
import { DbConnection } from '@n8n/db';
|
||||
import { Container } from '@n8n/di';
|
||||
import { DataSource } from '@n8n/typeorm';
|
||||
|
||||
const migration = 'AddSkillAssistantAvailability1792418677997';
|
||||
|
||||
describe('Skill Assistant availability migration', () => {
|
||||
let context: TestMigrationContext;
|
||||
|
||||
beforeAll(async () => {
|
||||
await Container.get(DbConnection).init();
|
||||
context = createTestMigrationContext(Container.get(DataSource));
|
||||
await context.queryRunner.clearDatabase();
|
||||
await context.queryRunner.release();
|
||||
await initDbUpToMigration(migration);
|
||||
context = createTestMigrationContext(Container.get(DataSource));
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await context?.queryRunner.release();
|
||||
await Container.get(DbConnection).close();
|
||||
});
|
||||
|
||||
it('defaults existing and new skills to false and preserves versions through up/down/up', async () => {
|
||||
const table = context.escape.tableName('skill');
|
||||
const versions = context.escape.tableName('skill_version');
|
||||
const col = context.escape.columnName;
|
||||
await context.runQuery(
|
||||
`INSERT INTO ${table} (${col('id')}, ${col('source')}) VALUES ('existing', 'ui')`,
|
||||
);
|
||||
await context.runQuery(
|
||||
`INSERT INTO ${versions} (${col('id')}, ${col('skillId')}, ${col('version')}, ${col('name')}, ${col('description')}, ${col('instructions')}, ${col('contentHash')}) VALUES ('0199e890-7471-7000-8000-000000000001', 'existing', 1, 'Tone', 'Writing style', 'Be brief.', '${'a'.repeat(64)}')`,
|
||||
);
|
||||
await context.queryRunner.release();
|
||||
await runSingleMigration(migration);
|
||||
context = createTestMigrationContext(Container.get(DataSource));
|
||||
await context.runQuery(
|
||||
`INSERT INTO ${table} (${col('id')}, ${col('source')}) VALUES ('new', 'agent')`,
|
||||
);
|
||||
const readFlags = async () =>
|
||||
await context.runQuery<Array<{ availableToAssistant: boolean | number }>>(
|
||||
`SELECT ${col('availableToAssistant')} FROM ${table}`,
|
||||
);
|
||||
expect((await readFlags()).map((row) => Boolean(row.availableToAssistant))).toEqual([
|
||||
false,
|
||||
false,
|
||||
]);
|
||||
await context.runQuery(
|
||||
`UPDATE ${table} SET ${col('availableToAssistant')} = true WHERE ${col('id')} = 'existing'`,
|
||||
);
|
||||
expect((await readFlags()).filter((row) => Boolean(row.availableToAssistant))).toHaveLength(1);
|
||||
|
||||
await context.queryRunner.release();
|
||||
await Container.get(DataSource).undoLastMigration();
|
||||
await runSingleMigration(migration);
|
||||
context = createTestMigrationContext(Container.get(DataSource));
|
||||
expect((await readFlags()).map((row) => Boolean(row.availableToAssistant))).toEqual([
|
||||
false,
|
||||
false,
|
||||
]);
|
||||
expect(await context.runQuery(`SELECT ${col('instructions')} FROM ${versions}`)).toEqual([
|
||||
{ instructions: 'Be brief.' },
|
||||
]);
|
||||
});
|
||||
});
|
||||
Loading…
Reference in New Issue
Block a user