Skip to content

Commit 479cd34

Browse files
v0.5.83: agent skills, concurrent workers for v8s, airweave integration
2 parents a3a99ed + 0cb6714 commit 479cd34

File tree

138 files changed

+15703
-1071
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

138 files changed

+15703
-1071
lines changed

apps/docs/components/icons.tsx

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1131,6 +1131,32 @@ export function AirtableIcon(props: SVGProps<SVGSVGElement>) {
11311131
)
11321132
}
11331133

1134+
export function AirweaveIcon(props: SVGProps<SVGSVGElement>) {
1135+
return (
1136+
<svg
1137+
{...props}
1138+
width='143'
1139+
height='143'
1140+
viewBox='0 0 143 143'
1141+
fill='none'
1142+
xmlns='http://www.w3.org/2000/svg'
1143+
>
1144+
<path
1145+
d='M89.8854 128.872C79.9165 123.339 66.7502 115.146 60.5707 107.642L60.0432 107.018C58.7836 105.5 57.481 104.014 56.1676 102.593C51.9152 97.9641 47.3614 93.7978 42.646 90.2021C40.7405 88.7487 38.7704 87.3492 36.8111 86.0789C35.7991 85.4222 34.8302 84.8193 33.9151 84.2703C31.6221 82.903 28.8338 82.5263 26.2716 83.2476C23.8385 83.9366 21.89 85.5406 20.7596 87.7476C18.5634 92.0323 20.0814 97.3289 24.2046 99.805C27.5204 101.786 30.7608 104.111 33.8398 106.717C34.2381 107.05 34.3996 107.578 34.2596 108.062C33.1292 112.185 31.9989 118.957 31.5682 121.67C30.6424 127.429 33.4737 133.081 38.5982 135.751L38.7812 135.848C41.0204 137 43.6472 136.946 45.8219 135.697C47.9858 134.459 49.353 132.231 49.4822 129.733C49.536 128.657 49.6006 127.58 49.676 126.59C49.719 126.062 50.042 125.632 50.5264 125.459C50.6772 125.406 50.8494 125.373 51.0001 125.373C51.3554 125.373 51.6784 125.513 51.9475 125.782C56.243 130.185 60.8829 134.169 65.7167 137.625C70.3674 140.951 75.8686 142.706 81.639 142.706C83.7383 142.706 85.8376 142.469 87.8938 141.995L88.1199 141.942C90.9943 141.274 93.029 139.024 93.4488 136.085C93.8687 133.146 92.4476 130.315 89.8747 128.883H89.8639L89.8854 128.872Z'
1146+
fill='currentColor'
1147+
/>
1148+
<path
1149+
d='M142.551 58.1747L142.529 58.0563C142.045 55.591 140.118 53.7069 137.598 53.2548C135.112 52.8134 132.754 53.8577 131.484 55.9893L131.408 56.1077C126.704 64.1604 120.061 71.6101 111.653 78.2956C109.446 80.0504 107.293 81.902 105.226 83.8075C103.644 85.2717 101.265 85.53 99.4452 84.4212C97.6474 83.3339 95.8495 82.1389 94.1055 80.8686C90.3268 78.1233 86.6772 74.9475 83.2753 71.4271C81.4989 69.597 79.798 67.6915 78.1939 65.7321C76.0408 63.1161 73.7477 60.5539 71.3685 58.1316C66.3195 52.9857 56.6089 45.9127 53.7453 43.878C53.3792 43.6304 53.1639 43.2428 53.0993 42.8014C53.0455 42.3601 53.1639 41.9509 53.4546 41.6064C55.274 39.4318 56.9965 37.1818 58.5683 34.921C60.2369 32.5311 60.786 29.6028 60.0862 26.8899C59.408 24.2523 57.6424 22.11 55.134 20.8827C50.9139 18.7942 45.8972 20.0968 43.2273 23.9293C40.8373 27.3636 38.0167 30.7332 34.8732 33.9306C34.5718 34.232 34.1304 34.3397 33.7213 34.1889C30.5239 33.1447 27.2296 32.2942 23.9461 31.659C23.7093 31.616 23.354 31.5514 22.9126 31.4975C16.4102 30.5286 10.1123 33.7798 7.21639 39.5717L7.1195 39.7548C6.18289 41.628 6.26902 43.8349 7.32405 45.6651C8.40061 47.5167 10.3277 48.701 12.4592 48.8194C13.4604 48.8732 14.4401 48.9378 15.3659 49.0024C15.7966 49.0347 16.1411 49.2823 16.3025 49.6914C16.4533 50.1112 16.3671 50.5419 16.0657 50.8541C12.147 54.8804 8.60515 59.1974 5.5262 63.6867C1.1446 70.0814 -0.481008 78.2095 1.08 85.9822L1.10154 86.1006C1.70441 89.0719 4.05131 91.2035 7.07644 91.5264C9.98315 91.8386 12.6099 90.3208 13.7619 87.6724L13.8265 87.5109C18.6925 75.8625 26.7559 65.5168 37.7907 56.7536C38.3182 56.3445 39.0072 56.28 39.567 56.5922C45.3373 59.768 50.8601 63.902 55.9738 68.8864C56.5982 69.4893 56.6089 70.5013 56.0168 71.1257C53.4761 73.8063 51.0862 76.6054 48.9115 79.469C47.2106 81.7083 47.5335 84.8949 49.6221 86.7358L53.3254 89.9977L53.2824 90.0409C53.8637 90.5576 54.445 91.0744 55.0264 91.5911L55.8123 92.194C56.9319 93.1844 58.3529 93.6365 59.8386 93.4858C61.3027 93.3351 62.67 92.56 63.5635 91.3758C65.1353 89.2873 66.8578 87.2525 68.6556 85.304C68.957 84.9702 69.3661 84.798 69.8075 84.7872C70.2705 84.7872 70.6257 84.9379 70.9164 85.2286C75.8147 90.0624 81.1114 94.3686 86.6772 97.9966C88.8626 99.4176 89.4978 102.26 88.1306 104.477C86.9248 106.448 85.7729 108.493 84.7179 110.539C83.5014 112.918 83.2968 115.738 84.1688 118.257C84.9978 120.68 86.7095 122.585 88.981 123.64C90.2514 124.232 91.5971 124.534 92.9859 124.534C96.5062 124.534 99.682 122.596 101.286 119.452C102.729 116.61 104.419 113.8 106.281 111.131C107.369 109.559 109.36 108.838 111.255 109.322C115.26 110.355 120.643 111.421 124.454 112.143C128.308 112.864 132.119 111.023 133.96 107.578L134.143 107.233C135.521 104.628 135.531 101.506 134.164 98.8901C132.786 96.2526 130.181 94.4655 127.21 94.121C126.478 94.0349 125.778 93.9488 125.11 93.8626C124.97 93.8411 124.852 93.8196 124.744 93.798L123.356 93.4751L124.357 92.4523C124.432 92.377 124.529 92.2801 124.658 92.194C128.771 88.8028 132.571 85.1963 135.962 81.4714C141.668 75.1951 144.122 66.4965 142.518 58.1747H142.529H142.551Z'
1150+
fill='currentColor'
1151+
/>
1152+
<path
1153+
d='M56.6506 14.3371C65.5861 19.6338 77.4067 27.3743 82.9833 34.1674C83.64 34.9532 84.2967 35.7391 84.9534 36.4927C86.1591 37.8815 86.2991 39.8731 85.2979 41.4233C83.4892 44.2116 81.4115 46.9569 79.1399 49.5945C77.4713 51.5107 77.4067 54.3098 78.9785 56.2476L79.0431 56.323C79.2261 56.5598 79.4306 56.8074 79.6136 57.0442C81.2931 59.1758 83.0801 61.2213 84.9211 63.1375C85.9007 64.1603 87.2249 64.7309 88.6352 64.7309L88.7644 65.5275L88.7429 64.7309C90.207 64.6986 91.6173 64.0526 92.5969 62.933C94.8362 60.4031 96.9247 57.744 98.8302 55.0633C100.133 53.2224 102.63 52.8026 104.525 54.1052C106.463 55.4402 108.465 56.7105 110.457 57.8839C112.793 59.2511 115.614 59.5095 118.165 58.5621C120.749 57.604 122.762 55.5694 123.656 52.9533C125.055 48.9055 123.257 44.2547 119.382 41.9078C116.755 40.3145 114.15 38.5166 111.674 36.5788C110.382 35.5561 109.833 33.8767 110.296 32.2941C111.437 28.3001 112.481 23.1218 113.148 19.4831C113.837 15.7259 112.147 11.8826 108.939 9.94477L108.562 9.72944C105.871 8.12537 102.587 8.00696 99.7668 9.40649C96.9247 10.8168 95.03 13.5405 94.6855 16.6733L94.6639 16.867C94.6209 17.2546 94.384 17.5453 94.018 17.6637C93.652 17.7821 93.2859 17.6852 93.0168 17.4269C89.0012 13.1422 84.738 9.25576 80.3134 5.8646C74.3708 1.31075 66.7811 -0.583999 59.4928 0.675575L59.1805 0.729423C56.1124 1.2677 53.7547 3.60383 53.1949 6.68279C52.6351 9.72946 53.9915 12.7223 56.6722 14.3048H56.6614L56.6506 14.3371Z'
1154+
fill='currentColor'
1155+
/>
1156+
</svg>
1157+
)
1158+
}
1159+
11341160
export function GoogleDocsIcon(props: SVGProps<SVGSVGElement>) {
11351161
return (
11361162
<svg
@@ -5436,3 +5462,24 @@ export function EnrichSoIcon(props: SVGProps<SVGSVGElement>) {
54365462
</svg>
54375463
)
54385464
}
5465+
5466+
export function AgentSkillsIcon(props: SVGProps<SVGSVGElement>) {
5467+
return (
5468+
<svg
5469+
{...props}
5470+
xmlns='http://www.w3.org/2000/svg'
5471+
width='16'
5472+
height='16'
5473+
viewBox='0 0 16 16'
5474+
fill='none'
5475+
>
5476+
<path
5477+
d='M8 1L14.0622 4.5V11.5L8 15L1.93782 11.5V4.5L8 1Z'
5478+
stroke='currentColor'
5479+
strokeWidth='1.5'
5480+
fill='none'
5481+
/>
5482+
<path d='M8 4.5L11 6.25V9.75L8 11.5L5 9.75V6.25L8 4.5Z' fill='currentColor' />
5483+
</svg>
5484+
)
5485+
}

apps/docs/components/ui/icon-mapping.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
A2AIcon,
88
AhrefsIcon,
99
AirtableIcon,
10+
AirweaveIcon,
1011
ApifyIcon,
1112
ApolloIcon,
1213
ArxivIcon,
@@ -141,6 +142,7 @@ export const blockTypeToIconMap: Record<string, IconComponent> = {
141142
a2a: A2AIcon,
142143
ahrefs: AhrefsIcon,
143144
airtable: AirtableIcon,
145+
airweave: AirweaveIcon,
144146
apify: ApifyIcon,
145147
apollo: ApolloIcon,
146148
arxiv: ArxivIcon,

apps/docs/content/docs/en/meta.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
"connections",
1111
"mcp",
1212
"copilot",
13+
"skills",
1314
"knowledgebase",
1415
"variables",
1516
"execution",
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
---
2+
title: Agent Skills
3+
---
4+
5+
import { Callout } from 'fumadocs-ui/components/callout'
6+
7+
Agent Skills are reusable packages of instructions that give your AI agents specialized capabilities. Based on the open [Agent Skills](https://agentskills.io) format, skills let you capture domain expertise, workflows, and best practices that agents can load on demand.
8+
9+
## How Skills Work
10+
11+
Skills use **progressive disclosure** to keep agent context lean:
12+
13+
1. **Discovery** — Only skill names and descriptions are included in the agent's system prompt (~50-100 tokens each)
14+
2. **Activation** — When the agent decides a skill is relevant, it calls the `load_skill` tool to load the full instructions into context
15+
3. **Execution** — The agent follows the loaded instructions to complete the task
16+
17+
This means you can attach many skills to an agent without bloating its context window. The agent only loads what it needs.
18+
19+
## Creating Skills
20+
21+
Go to **Settings** and select **Skills** under the Tools section.
22+
23+
![Manage Skills](/static/skills/manage-skills.png)
24+
25+
Click **Add** to create a new skill with three fields:
26+
27+
| Field | Description |
28+
|-------|-------------|
29+
| **Name** | A kebab-case identifier (e.g. `sql-expert`, `code-reviewer`). Max 64 characters. |
30+
| **Description** | A short explanation of what the skill does and when to use it. This is what the agent reads to decide whether to activate the skill. Max 1024 characters. |
31+
| **Content** | The full skill instructions in markdown. This is loaded when the agent activates the skill. |
32+
33+
<Callout type="info">
34+
The description is critical — it's the only thing the agent sees before deciding to load a skill. Be specific about when and why the skill should be used.
35+
</Callout>
36+
37+
### Writing Good Skill Content
38+
39+
Skill content follows the same conventions as [SKILL.md files](https://agentskills.io/specification):
40+
41+
```markdown
42+
# SQL Expert
43+
44+
## When to use this skill
45+
Use when the user asks you to write, optimize, or debug SQL queries.
46+
47+
## Instructions
48+
1. Always ask which database engine (PostgreSQL, MySQL, SQLite)
49+
2. Use CTEs over subqueries for readability
50+
3. Add index recommendations when relevant
51+
4. Explain query plans for optimization requests
52+
53+
## Common Patterns
54+
...
55+
```
56+
57+
**Recommended structure:**
58+
- **When to use** — Specific triggers and scenarios
59+
- **Instructions** — Step-by-step guidance with numbered lists
60+
- **Examples** — Input/output samples showing expected behavior
61+
- **Common Patterns** — Reusable approaches for frequent tasks
62+
- **Edge Cases** — Gotchas and special considerations
63+
64+
Keep skills focused and under 500 lines. If a skill grows too large, split it into multiple specialized skills.
65+
66+
## Adding Skills to an Agent
67+
68+
Open any **Agent** block and find the **Skills** dropdown below the tools section. Select the skills you want the agent to have access to.
69+
70+
![Add Skill](/static/skills/add-skill.png)
71+
72+
Selected skills appear as cards that you can click to edit or remove.
73+
74+
### What Happens at Runtime
75+
76+
When the workflow runs:
77+
78+
1. The agent's system prompt includes an `<available_skills>` section listing each skill's name and description
79+
2. A `load_skill` tool is automatically added to the agent's available tools
80+
3. When the agent determines a skill is relevant to the current task, it calls `load_skill` with the skill name
81+
4. The full skill content is returned as a tool response, giving the agent detailed instructions
82+
83+
This works across all supported LLM providers — the `load_skill` tool uses standard tool-calling, so no provider-specific configuration is needed.
84+
85+
## Common Use Cases
86+
87+
Skills are most valuable when agents need specialized knowledge or multi-step workflows:
88+
89+
**Domain Expertise**
90+
- `api-integration-expert` — Best practices for calling specific APIs (authentication, rate limiting, error handling)
91+
- `data-transformation` — ETL patterns, data cleaning, and validation rules
92+
- `code-reviewer` — Code review guidelines specific to your team's standards
93+
94+
**Workflow Templates**
95+
- `bug-investigation` — Step-by-step debugging methodology (reproduce → isolate → test → fix)
96+
- `feature-implementation` — Development workflow from requirements to deployment
97+
- `document-generator` — Templates and formatting rules for technical documentation
98+
99+
**Company-Specific Knowledge**
100+
- `our-architecture` — System architecture diagrams, service dependencies, and deployment processes
101+
- `style-guide` — Brand guidelines, writing tone, UI/UX patterns
102+
- `customer-onboarding` — Standard procedures and common customer questions
103+
104+
**When to use skills vs. agent instructions:**
105+
- Use **skills** for knowledge that applies across multiple workflows or changes frequently
106+
- Use **agent instructions** for task-specific context that's unique to a single agent
107+
108+
## Best Practices
109+
110+
**Writing Effective Descriptions**
111+
- **Be specific and keyword-rich** — Instead of "Helps with SQL", write "Write optimized SQL queries for PostgreSQL, MySQL, and SQLite, including index recommendations and query plan analysis"
112+
- **Include activation triggers** — Mention specific words or phrases that should prompt the skill (e.g., "Use when the user mentions PDFs, forms, or document extraction")
113+
- **Keep it under 200 words** — Agents scan descriptions quickly; make every word count
114+
115+
**Skill Scope and Organization**
116+
- **One skill per domain** — A focused `sql-expert` skill works better than a broad `database-everything` skill
117+
- **Limit to 5-10 skills per agent** — More skills = more decision overhead; start small and add as needed
118+
- **Split large skills** — If a skill exceeds 500 lines, break it into focused sub-skills
119+
120+
**Content Structure**
121+
- **Use markdown formatting** — Headers, lists, and code blocks help agents parse and follow instructions
122+
- **Provide examples** — Show input/output pairs so agents understand expected behavior
123+
- **Be explicit about edge cases** — Don't assume agents will infer special handling
124+
125+
**Testing and Iteration**
126+
- **Test activation** — Run your workflow and verify the agent loads the skill when expected
127+
- **Check for false positives** — Make sure skills aren't activating when they shouldn't
128+
- **Refine descriptions** — If a skill isn't loading when needed, add more keywords to the description
129+
130+
## Learn More
131+
132+
- [Agent Skills specification](https://agentskills.io) — The open format for portable agent skills
133+
- [Example skills](https://github.com/anthropics/skills) — Browse community skill examples
134+
- [Best practices](https://agentskills.io/what-are-skills) — Writing effective skills
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
---
2+
title: Airweave
3+
description: Search your synced data collections
4+
---
5+
6+
import { BlockInfoCard } from "@/components/ui/block-info-card"
7+
8+
<BlockInfoCard
9+
type="airweave"
10+
color="#6366F1"
11+
/>
12+
13+
{/* MANUAL-CONTENT-START:intro */}
14+
[Airweave](https://airweave.ai/) is an AI-powered semantic search platform that helps you discover and retrieve knowledge across all your synced data sources. Built for modern teams, Airweave enables fast, relevant search results using neural, hybrid, or keyword-based strategies tailored to your needs.
15+
16+
With Airweave, you can:
17+
18+
- **Search smarter**: Use natural language queries to uncover information stored across your connected tools and databases
19+
- **Unify your data**: Seamlessly access content from sources like code, docs, chat, emails, cloud files, and more
20+
- **Customize retrieval**: Select between hybrid (semantic + keyword), neural, or keyword search strategies for optimal results
21+
- **Boost recall**: Expand search queries with AI to find more comprehensive answers
22+
- **Rerank results using AI**: Prioritize the most relevant answers with powerful language models
23+
- **Get instant answers**: Generate clear, AI-powered responses synthesized from your data
24+
25+
In Sim, the Airweave integration empowers your agents to search, summarize, and extract insights from all your organization’s data via a single tool. Use Airweave to drive rich, contextual knowledge retrieval within your workflows—whether answering questions, generating summaries, or supporting dynamic decision-making.
26+
{/* MANUAL-CONTENT-END */}
27+
28+
## Usage Instructions
29+
30+
Search across your synced data sources using Airweave. Supports semantic search with hybrid, neural, or keyword retrieval strategies. Optionally generate AI-powered answers from search results.
31+
32+
33+
34+
## Tools
35+
36+
### `airweave_search`
37+
38+
Search your synced data collections using Airweave. Supports semantic search with hybrid, neural, or keyword retrieval strategies. Optionally generate AI-powered answers from search results.
39+
40+
#### Input
41+
42+
| Parameter | Type | Required | Description |
43+
| --------- | ---- | -------- | ----------- |
44+
| `apiKey` | string | Yes | Airweave API Key for authentication |
45+
| `collectionId` | string | Yes | The readable ID of the collection to search |
46+
| `query` | string | Yes | The search query text |
47+
| `limit` | number | No | Maximum number of results to return \(default: 100\) |
48+
| `retrievalStrategy` | string | No | Retrieval strategy: hybrid \(default\), neural, or keyword |
49+
| `expandQuery` | boolean | No | Generate query variations to improve recall |
50+
| `rerank` | boolean | No | Reorder results for improved relevance using LLM |
51+
| `generateAnswer` | boolean | No | Generate a natural-language answer to the query |
52+
53+
#### Output
54+
55+
| Parameter | Type | Description |
56+
| --------- | ---- | ----------- |
57+
| `results` | array | Search results with content, scores, and metadata from your synced data |
58+
|`entity_id` | string | Unique identifier for the search result entity |
59+
|`source_name` | string | Name of the data source \(e.g., "GitHub", "Slack"\) |
60+
|`md_content` | string | Markdown-formatted content of the result |
61+
|`score` | number | Relevance score from the search |
62+
|`metadata` | object | Additional metadata associated with the result |
63+
|`breadcrumbs` | array | Navigation path to the result within its source |
64+
|`url` | string | URL to the original content |
65+
| `completion` | string | AI-generated answer to the query \(when generateAnswer is enabled\) |
66+
67+

apps/docs/content/docs/en/tools/meta.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
"a2a",
55
"ahrefs",
66
"airtable",
7+
"airweave",
78
"apify",
89
"apollo",
910
"arxiv",
27.9 KB
Loading
56.2 KB
Loading

apps/sim/app/api/a2a/agents/[agentId]/route.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { eq } from 'drizzle-orm'
55
import { type NextRequest, NextResponse } from 'next/server'
66
import { generateAgentCard, generateSkillsFromWorkflow } from '@/lib/a2a/agent-card'
77
import type { AgentCapabilities, AgentSkill } from '@/lib/a2a/types'
8-
import { checkHybridAuth } from '@/lib/auth/hybrid'
8+
import { checkSessionOrInternalAuth } from '@/lib/auth/hybrid'
99
import { getRedisClient } from '@/lib/core/config/redis'
1010
import { loadWorkflowFromNormalizedTables } from '@/lib/workflows/persistence/utils'
1111
import { checkWorkspaceAccess } from '@/lib/workspaces/permissions/utils'
@@ -40,7 +40,7 @@ export async function GET(request: NextRequest, { params }: { params: Promise<Ro
4040
}
4141

4242
if (!agent.agent.isPublished) {
43-
const auth = await checkHybridAuth(request, { requireWorkflowId: false })
43+
const auth = await checkSessionOrInternalAuth(request, { requireWorkflowId: false })
4444
if (!auth.success) {
4545
return NextResponse.json({ error: 'Agent not published' }, { status: 404 })
4646
}
@@ -81,7 +81,7 @@ export async function PUT(request: NextRequest, { params }: { params: Promise<Ro
8181
const { agentId } = await params
8282

8383
try {
84-
const auth = await checkHybridAuth(request, { requireWorkflowId: false })
84+
const auth = await checkSessionOrInternalAuth(request, { requireWorkflowId: false })
8585
if (!auth.success || !auth.userId) {
8686
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
8787
}
@@ -151,7 +151,7 @@ export async function DELETE(request: NextRequest, { params }: { params: Promise
151151
const { agentId } = await params
152152

153153
try {
154-
const auth = await checkHybridAuth(request, { requireWorkflowId: false })
154+
const auth = await checkSessionOrInternalAuth(request, { requireWorkflowId: false })
155155
if (!auth.success || !auth.userId) {
156156
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
157157
}
@@ -189,7 +189,7 @@ export async function POST(request: NextRequest, { params }: { params: Promise<R
189189
const { agentId } = await params
190190

191191
try {
192-
const auth = await checkHybridAuth(request, { requireWorkflowId: false })
192+
const auth = await checkSessionOrInternalAuth(request, { requireWorkflowId: false })
193193
if (!auth.success || !auth.userId) {
194194
logger.warn('A2A agent publish auth failed:', { error: auth.error, hasUserId: !!auth.userId })
195195
return NextResponse.json({ error: auth.error || 'Unauthorized' }, { status: 401 })

0 commit comments

Comments
 (0)