Compare commits
65
Commits
skill
..
deploy/dev
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2bb01984ed | ||
|
|
5c4f4fd1ef | ||
|
|
54843971ac | ||
|
|
5ec5d3aeb9 | ||
|
|
d661b53e49 | ||
|
|
fd1e777f85 | ||
|
|
e5f77ce185 | ||
|
|
99929d1c16 | ||
|
|
c699aa11db | ||
|
|
06cd0b56ac | ||
|
|
241a9e1fec | ||
|
|
3d79689fb5 | ||
|
|
9f050f7957 | ||
|
|
cb691d47d3 | ||
|
|
04f5ee58d0 | ||
|
|
f5cff724f4 | ||
|
|
1f4ccafdea | ||
|
|
163049f6ca | ||
|
|
65e7507ca3 | ||
|
|
ba157f9604 | ||
|
|
0dc913630e | ||
|
|
875cd30b1f | ||
|
|
aa4a32ae84 | ||
|
|
8573e14777 | ||
|
|
1855be234c | ||
|
|
9bb960ff12 | ||
|
|
1c14c7d467 | ||
|
|
61faec16ca | ||
|
|
57c836e692 | ||
|
|
626cc282b1 | ||
|
|
52624d54e3 | ||
|
|
5ce038ef92 | ||
|
|
30f4d4c0c6 | ||
|
|
510679a7d1 | ||
|
|
9237f2a14a | ||
|
|
bd178c7b29 | ||
|
|
d80947aa72 | ||
|
|
1618c37d26 | ||
|
|
701ab64462 | ||
|
|
b3298800e9 | ||
|
|
0f1c6b3f78 | ||
|
|
9b4b246aad | ||
|
|
1bd654a289 | ||
|
|
fc70329bdb | ||
|
|
cd8a82fbd4 | ||
|
|
550cb7eff5 | ||
|
|
2e748c16e9 | ||
|
|
577012b66d | ||
|
|
251c324180 | ||
|
|
865a618fd5 | ||
|
|
991116990a | ||
|
|
eb5d1da0e8 | ||
|
|
dce3b7a7fc | ||
|
|
be386aba3b | ||
|
|
02e51e7d7c | ||
|
|
96b6d4f2c0 | ||
|
|
4c84c5957d | ||
|
|
34613ecdc5 | ||
|
|
6a14245401 | ||
|
|
a758ca2aef | ||
|
|
9e60d4e213 | ||
|
|
ef29c8442c | ||
|
|
a1b45415ac | ||
|
|
7fc46d75bd | ||
|
|
953a4ef0ca |
+110
-23
@@ -18,31 +18,109 @@ branch_labels = None
|
|||||||
depends_on = None
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
|
def _is_pg(conn) -> bool:
|
||||||
|
return conn.dialect.name == "postgresql"
|
||||||
|
|
||||||
|
|
||||||
|
def _uuid_column(name: str, *, nullable: bool = False, primary_key: bool = False) -> sa.Column:
|
||||||
|
kwargs = {"nullable": nullable, "primary_key": primary_key}
|
||||||
|
if primary_key and _is_pg(op.get_bind()):
|
||||||
|
kwargs["server_default"] = sa.text("uuidv7()")
|
||||||
|
return sa.Column(name, models.types.StringUUID(), **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
def _has_table(table_name: str) -> bool:
|
||||||
|
return sa.inspect(op.get_bind()).has_table(table_name)
|
||||||
|
|
||||||
|
|
||||||
|
def _has_column(table_name: str, column_name: str) -> bool:
|
||||||
|
return any(
|
||||||
|
column["name"] == column_name for column in sa.inspect(op.get_bind()).get_columns(table_name)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _has_unique_constraint(table_name: str, constraint_name: str) -> bool:
|
||||||
|
return any(
|
||||||
|
constraint["name"] == constraint_name
|
||||||
|
for constraint in sa.inspect(op.get_bind()).get_unique_constraints(table_name)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def upgrade():
|
def upgrade():
|
||||||
|
if not _has_table("agent_debug_conversations"):
|
||||||
|
op.create_table(
|
||||||
|
"agent_debug_conversations",
|
||||||
|
_uuid_column("id", primary_key=True),
|
||||||
|
sa.Column("tenant_id", models.types.StringUUID(), nullable=False),
|
||||||
|
sa.Column("agent_id", models.types.StringUUID(), nullable=False),
|
||||||
|
sa.Column("app_id", models.types.StringUUID(), nullable=False),
|
||||||
|
sa.Column("account_id", models.types.StringUUID(), nullable=False),
|
||||||
|
sa.Column("conversation_id", models.types.StringUUID(), nullable=False),
|
||||||
|
sa.Column(
|
||||||
|
"draft_type",
|
||||||
|
sa.String(length=32),
|
||||||
|
nullable=False,
|
||||||
|
server_default=sa.text("'debug_build'"),
|
||||||
|
),
|
||||||
|
sa.Column("created_at", sa.DateTime(), server_default=sa.func.current_timestamp(), nullable=False),
|
||||||
|
sa.Column("updated_at", sa.DateTime(), server_default=sa.func.current_timestamp(), nullable=False),
|
||||||
|
sa.PrimaryKeyConstraint("id", name=op.f("agent_debug_conversation_pkey")),
|
||||||
|
sa.UniqueConstraint(
|
||||||
|
"tenant_id",
|
||||||
|
"agent_id",
|
||||||
|
"account_id",
|
||||||
|
"draft_type",
|
||||||
|
name=op.f("agent_debug_conversation_agent_account_draft_type_unique"),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
op.create_index(
|
||||||
|
"agent_debug_conversation_conversation_idx",
|
||||||
|
"agent_debug_conversations",
|
||||||
|
["conversation_id"],
|
||||||
|
)
|
||||||
|
op.create_index(
|
||||||
|
"agent_debug_conversation_account_idx",
|
||||||
|
"agent_debug_conversations",
|
||||||
|
["tenant_id", "account_id"],
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
# Existing pointers have always represented Build chat because the Agent
|
# Existing pointers have always represented Build chat because the Agent
|
||||||
# detail API exposes them as ``debug_conversation_id`` for that surface.
|
# detail API exposes them as ``debug_conversation_id`` for that surface.
|
||||||
op.add_column(
|
if not _has_column("agent_debug_conversations", "draft_type"):
|
||||||
|
op.add_column(
|
||||||
|
"agent_debug_conversations",
|
||||||
|
sa.Column(
|
||||||
|
"draft_type",
|
||||||
|
sa.String(length=32),
|
||||||
|
nullable=False,
|
||||||
|
server_default=sa.text("'debug_build'"),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
if _has_unique_constraint(
|
||||||
"agent_debug_conversations",
|
"agent_debug_conversations",
|
||||||
sa.Column(
|
|
||||||
"draft_type",
|
|
||||||
sa.String(length=32),
|
|
||||||
nullable=False,
|
|
||||||
server_default=sa.text("'debug_build'"),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
op.drop_constraint(
|
|
||||||
"agent_debug_conversation_agent_account_unique",
|
"agent_debug_conversation_agent_account_unique",
|
||||||
|
):
|
||||||
|
op.drop_constraint(
|
||||||
|
"agent_debug_conversation_agent_account_unique",
|
||||||
|
"agent_debug_conversations",
|
||||||
|
type_="unique",
|
||||||
|
)
|
||||||
|
if not _has_unique_constraint(
|
||||||
"agent_debug_conversations",
|
"agent_debug_conversations",
|
||||||
type_="unique",
|
|
||||||
)
|
|
||||||
op.create_unique_constraint(
|
|
||||||
"agent_debug_conversation_agent_account_draft_type_unique",
|
"agent_debug_conversation_agent_account_draft_type_unique",
|
||||||
"agent_debug_conversations",
|
):
|
||||||
["tenant_id", "agent_id", "account_id", "draft_type"],
|
op.create_unique_constraint(
|
||||||
)
|
"agent_debug_conversation_agent_account_draft_type_unique",
|
||||||
|
"agent_debug_conversations",
|
||||||
|
["tenant_id", "agent_id", "account_id", "draft_type"],
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def downgrade():
|
def downgrade():
|
||||||
|
if not _has_table("agent_debug_conversations"):
|
||||||
|
return
|
||||||
|
|
||||||
debug_conversations = sa.table(
|
debug_conversations = sa.table(
|
||||||
"agent_debug_conversations",
|
"agent_debug_conversations",
|
||||||
sa.column("tenant_id", models.types.StringUUID()),
|
sa.column("tenant_id", models.types.StringUUID()),
|
||||||
@@ -64,14 +142,23 @@ def downgrade():
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
op.drop_constraint(
|
if _has_unique_constraint(
|
||||||
|
"agent_debug_conversations",
|
||||||
"agent_debug_conversation_agent_account_draft_type_unique",
|
"agent_debug_conversation_agent_account_draft_type_unique",
|
||||||
|
):
|
||||||
|
op.drop_constraint(
|
||||||
|
"agent_debug_conversation_agent_account_draft_type_unique",
|
||||||
|
"agent_debug_conversations",
|
||||||
|
type_="unique",
|
||||||
|
)
|
||||||
|
if not _has_unique_constraint(
|
||||||
"agent_debug_conversations",
|
"agent_debug_conversations",
|
||||||
type_="unique",
|
|
||||||
)
|
|
||||||
op.create_unique_constraint(
|
|
||||||
"agent_debug_conversation_agent_account_unique",
|
"agent_debug_conversation_agent_account_unique",
|
||||||
"agent_debug_conversations",
|
):
|
||||||
["tenant_id", "agent_id", "account_id"],
|
op.create_unique_constraint(
|
||||||
)
|
"agent_debug_conversation_agent_account_unique",
|
||||||
op.drop_column("agent_debug_conversations", "draft_type")
|
"agent_debug_conversations",
|
||||||
|
["tenant_id", "agent_id", "account_id"],
|
||||||
|
)
|
||||||
|
if _has_column("agent_debug_conversations", "draft_type"):
|
||||||
|
op.drop_column("agent_debug_conversations", "draft_type")
|
||||||
|
|||||||
+21
@@ -0,0 +1,21 @@
|
|||||||
|
"""merge skill and agent debug conversation heads
|
||||||
|
|
||||||
|
Revision ID: e9f4a1b2c3d5
|
||||||
|
Revises: a4f8d2c9e1b0, d2825e7b9c10
|
||||||
|
Create Date: 2026-07-23 15:00:00.000000
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = "e9f4a1b2c3d5"
|
||||||
|
down_revision = ("a4f8d2c9e1b0", "d2825e7b9c10")
|
||||||
|
branch_labels = None
|
||||||
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
pass
|
||||||
@@ -1599,7 +1599,9 @@ class TenantService:
|
|||||||
return updated_accounts
|
return updated_accounts
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def iter_member_account_id_batches(tenant_id: str, batch_size: int, *, session: Session) -> Iterator[list[str]]:
|
def iter_member_account_id_batches(
|
||||||
|
tenant_id: str, batch_size: int, *, session: Session
|
||||||
|
) -> Iterator[list[str]]:
|
||||||
"""Yield workspace member account ids in bounded, ordered batches."""
|
"""Yield workspace member account ids in bounded, ordered batches."""
|
||||||
offset = 0
|
offset = 0
|
||||||
while True:
|
while True:
|
||||||
|
|||||||
@@ -285,7 +285,9 @@ class TagService:
|
|||||||
raise NotFound("Snippet not found")
|
raise NotFound("Snippet not found")
|
||||||
elif type == "skill":
|
elif type == "skill":
|
||||||
skill = session.scalar(
|
skill = session.scalar(
|
||||||
select(Skill).where(Skill.tenant_id == current_user.current_tenant_id, Skill.id == target_id).limit(1)
|
select(Skill)
|
||||||
|
.where(Skill.tenant_id == current_user.current_tenant_id, Skill.id == target_id)
|
||||||
|
.limit(1)
|
||||||
)
|
)
|
||||||
if not skill:
|
if not skill:
|
||||||
raise NotFound("Skill not found")
|
raise NotFound("Skill not found")
|
||||||
|
|||||||
@@ -616,7 +616,9 @@ def test_manifest_appends_published_workspace_skills() -> None:
|
|||||||
kind=AgentConfigVersionKind.DRAFT,
|
kind=AgentConfigVersionKind.DRAFT,
|
||||||
writable=False,
|
writable=False,
|
||||||
soul=_soul(
|
soul=_soul(
|
||||||
config_skills=[AgentConfigSkillRefConfig(name="alpha", description="Alpha skill", file_id="tool-file-1")]
|
config_skills=[
|
||||||
|
AgentConfigSkillRefConfig(name="alpha", description="Alpha skill", file_id="tool-file-1")
|
||||||
|
]
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ export type GetTagsData = {
|
|||||||
path?: never
|
path?: never
|
||||||
query?: {
|
query?: {
|
||||||
keyword?: string
|
keyword?: string
|
||||||
type?: string
|
type?: '' | 'app' | 'knowledge' | 'skill' | 'snippet'
|
||||||
}
|
}
|
||||||
url: '/tags'
|
url: '/tags'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ export const zTagBasePayload = z.object({
|
|||||||
|
|
||||||
export const zGetTagsQuery = z.object({
|
export const zGetTagsQuery = z.object({
|
||||||
keyword: z.string().optional(),
|
keyword: z.string().optional(),
|
||||||
type: z.string().optional().default(''),
|
type: z.enum(['', 'app', 'knowledge', 'skill', 'snippet']).optional().default(''),
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -728,10 +728,25 @@ export type SkillResponse = {
|
|||||||
visibility: string
|
visibility: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type SkillAssistModelPayload = {
|
||||||
|
model: string
|
||||||
|
model_settings?: { [key: string]: unknown } | null
|
||||||
|
plugin_id?: string | null
|
||||||
|
provider: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type SkillAssistAttachmentPayload = {
|
||||||
|
mime_type?: string | null
|
||||||
|
name: string
|
||||||
|
size?: number | null
|
||||||
|
tool_file_id: string
|
||||||
|
}
|
||||||
|
|
||||||
export type SkillAssistMessagePayload = {
|
export type SkillAssistMessagePayload = {
|
||||||
attachments?: Array<SkillAssistAttachmentPayload>
|
attachments?: Array<SkillAssistAttachmentPayload>
|
||||||
message: string
|
message: string
|
||||||
model?: SkillAssistModelPayload | null
|
model?: SkillAssistModelPayload | null
|
||||||
|
target_path?: string | null
|
||||||
}
|
}
|
||||||
|
|
||||||
export type SkillDraftFileOperationPayload = {
|
export type SkillDraftFileOperationPayload = {
|
||||||
@@ -1717,22 +1732,6 @@ export type SkillTagResponse = {
|
|||||||
tag: string
|
tag: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export type SkillAssistAttachmentPayload = {
|
|
||||||
mime_type?: string | null
|
|
||||||
name: string
|
|
||||||
size?: number | null
|
|
||||||
tool_file_id: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export type SkillAssistModelPayload = {
|
|
||||||
model: string
|
|
||||||
model_settings?: {
|
|
||||||
[key: string]: unknown
|
|
||||||
} | null
|
|
||||||
plugin_id?: string | null
|
|
||||||
provider: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export type SkillDraftFileOperation =
|
export type SkillDraftFileOperation =
|
||||||
| 'delete'
|
| 'delete'
|
||||||
| 'mkdir'
|
| 'mkdir'
|
||||||
@@ -1752,10 +1751,10 @@ export type SkillDraftTreeItemPayload = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type SkillReferenceResponse = {
|
export type SkillReferenceResponse = {
|
||||||
|
agent_id: string
|
||||||
agent_icon?: string | null
|
agent_icon?: string | null
|
||||||
agent_icon_background?: string | null
|
agent_icon_background?: string | null
|
||||||
agent_icon_type?: string | null
|
agent_icon_type?: string | null
|
||||||
agent_id: string
|
|
||||||
app_id?: string | null
|
app_id?: string | null
|
||||||
display_name: string
|
display_name: string
|
||||||
name: string
|
name: string
|
||||||
|
|||||||
@@ -1527,6 +1527,7 @@ export const zSkillAssistMessagePayload = z.object({
|
|||||||
attachments: z.array(zSkillAssistAttachmentPayload).max(10).optional(),
|
attachments: z.array(zSkillAssistAttachmentPayload).max(10).optional(),
|
||||||
message: z.string().min(1).max(8000),
|
message: z.string().min(1).max(8000),
|
||||||
model: zSkillAssistModelPayload.nullish(),
|
model: zSkillAssistModelPayload.nullish(),
|
||||||
|
target_path: z.string().nullish(),
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1559,10 +1560,10 @@ export const zSkillDraftFileOperationPayload = z.object({
|
|||||||
* SkillReferenceResponse
|
* SkillReferenceResponse
|
||||||
*/
|
*/
|
||||||
export const zSkillReferenceResponse = z.object({
|
export const zSkillReferenceResponse = z.object({
|
||||||
|
agent_id: z.string(),
|
||||||
agent_icon: z.string().nullish(),
|
agent_icon: z.string().nullish(),
|
||||||
agent_icon_background: z.string().nullish(),
|
agent_icon_background: z.string().nullish(),
|
||||||
agent_icon_type: z.string().nullish(),
|
agent_icon_type: z.string().nullish(),
|
||||||
agent_id: z.string(),
|
|
||||||
app_id: z.string().nullish(),
|
app_id: z.string().nullish(),
|
||||||
display_name: z.string(),
|
display_name: z.string(),
|
||||||
name: z.string(),
|
name: z.string(),
|
||||||
|
|||||||
@@ -422,6 +422,7 @@ describe('SkillsPage', () => {
|
|||||||
it('does not show export for an unpublished skill', async () => {
|
it('does not show export for an unpublished skill', async () => {
|
||||||
const user = userEvent.setup()
|
const user = userEvent.setup()
|
||||||
mocks.skills = [createSkill({ latest_published_version_id: null })]
|
mocks.skills = [createSkill({ latest_published_version_id: null })]
|
||||||
|
mocks.skillPages = [mocks.skills]
|
||||||
renderSkillsPage()
|
renderSkillsPage()
|
||||||
|
|
||||||
await user.click(
|
await user.click(
|
||||||
|
|||||||
Reference in New Issue
Block a user