Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion admin/nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,12 @@ export default defineNuxtConfig({
runtimeConfig: {
public: {
ranchVersion: rootRanchVersion(),
apiUrl: '',
// Prod (k8s) sets NUXT_PUBLIC_API_URL, which Nuxt's runtimeConfig env
// override picks up automatically. Local `ranch dev` only sets plain
// API_URL (see admin/.env) — without this fallback, apiUrl stays ''
// and the axios client resolves requests against its own origin
// instead of the api.
apiUrl: process.env.API_URL || '',
},
},
app: {
Expand Down
2 changes: 1 addition & 1 deletion admin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"private": true,
"type": "module",
"scripts": {
"predev": "openapi-ts",
"predev": "node ../scripts/wait-for-swagger.mjs && openapi-ts",
"dev": "nuxt dev --port 3001",
"prebuild": "openapi-ts",
"build": "nuxt build",
Expand Down
5 changes: 5 additions & 0 deletions api/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ services:
# 17900 → 7900 auth-proxy /live + /websockify + /vnc/* (open this in a browser)
browserless:
image: ghcr.io/cleanslice/browser-pool:latest
# Only published for linux/amd64 (see k8s/browser-pool-image/README.md) —
# without this, `docker compose up` on Apple Silicon fails with
# "no matching manifest for linux/arm64/v8". Runs fine under Docker
# Desktop's Rosetta/QEMU emulation.
platform: linux/amd64
container_name: ranch-browserless
ports:
- '13000:3000'
Expand Down
5 changes: 3 additions & 2 deletions api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,19 @@
"start:prod": "node dist/main",
"generate:swagger": "node dist/generate-swagger.js",
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
"pretest": "npm run generate",
"test": "jest --passWithNoTests",
"test:watch": "jest --watch",
"test:cov": "jest --coverage",
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
"test:e2e": "jest --config ./test/jest-e2e.json",
"generate": "npx prisma-import --force",
"generate": "npx prisma-import --force && DATABASE_URL=${DATABASE_URL:-postgresql://dummy:dummy@localhost:5432/dummy} npx prisma generate",
"premigrate": "npx prisma-import --force",
"migrate": "dotenv -e .env.dev -- npx prisma migrate dev --name auto && dotenv -e .env.dev -- npx prisma generate",
"migrate:reset": "dotenv -e .env.dev -- npx prisma migrate reset --force",
"migrate:prod": "dotenv -e .env.prod -- npx prisma migrate deploy",
"studio": "dotenv -e .env.dev -- npx prisma studio",
"docker": "docker compose up -d",
"docker": "bash ../scripts/docker-up.sh",
"freeport": "lsof -ti:3333 | xargs kill -9 2>/dev/null || true",
"predev": "npm run docker && npm run migrate && npm run freeport"
},
Expand Down
7 changes: 6 additions & 1 deletion app/nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,12 @@ export default defineNuxtConfig({
runtimeConfig: {
public: {
ranchVersion: rootRanchVersion(),
apiUrl: '',
// Prod (k8s) sets NUXT_PUBLIC_API_URL, which Nuxt's runtimeConfig env
// override picks up automatically. Local `ranch dev` only sets plain
// API_URL (see app/.env) — without this fallback, apiUrl stays ''
// and the axios client resolves requests against its own origin
// instead of the api.
apiUrl: process.env.API_URL || '',
},
},
app: {
Expand Down
2 changes: 1 addition & 1 deletion app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"private": true,
"type": "module",
"scripts": {
"predev": "openapi-ts",
"predev": "node ../scripts/wait-for-swagger.mjs && openapi-ts",
"dev": "nuxt dev --port 3000",
"prebuild": "openapi-ts",
"build": "nuxt build",
Expand Down
35 changes: 32 additions & 3 deletions app/slices/setup/api/data/repositories/api/schemas.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ export const UserRoleTypesSchema = {
type: "string",
enum: ["Owner", "Admin", "User", "Agent"],
description:
"Server filters Owner/Admin out regardless of what is passed; embed keys cannot grant platform-admin to a visitor.",
"Server filters Owner/Admin out unless the presenting API key carries the embed:mint-admin scope; plain embed keys cannot grant platform-admin to a visitor.",
} as const;

export const EmbedTokenDtoSchema = {
Expand All @@ -346,7 +346,7 @@ export const EmbedTokenDtoSchema = {
roles: {
type: "array",
description:
"Server filters Owner/Admin out regardless of what is passed; embed keys cannot grant platform-admin to a visitor.",
"Server filters Owner/Admin out unless the presenting API key carries the embed:mint-admin scope; plain embed keys cannot grant platform-admin to a visitor.",
items: {
$ref: "#/components/schemas/UserRoleTypes",
},
Expand All @@ -362,7 +362,7 @@ export const EmbedTokenDtoSchema = {

export const ApiKeyScopeTypesSchema = {
type: "string",
enum: ["embed:mint", "admin"],
enum: ["embed:mint", "embed:mint-admin", "admin"],
} as const;

export const CreateApiKeyDtoSchema = {
Expand Down Expand Up @@ -602,6 +602,23 @@ export const AddFromSitemapResultDtoSchema = {
required: ["added", "discovered"],
} as const;

export const AddFromArchiveResultDtoSchema = {
type: "object",
properties: {
detected: {
type: "number",
example: 288,
description:
"Number of ingestable files detected in the archive. Import runs in the background; refresh the sources list to watch them appear.",
},
started: {
type: "boolean",
example: true,
},
},
required: ["detected", "started"],
} as const;

export const AgentPodStatusDtoSchema = {
type: "object",
properties: {
Expand Down Expand Up @@ -973,6 +990,18 @@ export const SaveFileDtoSchema = {
required: ["content"],
} as const;

export const DeleteFilesDtoSchema = {
type: "object",
properties: {
deleted: {
type: "number",
example: 3,
description: "Number of S3 objects deleted by this request.",
},
},
required: ["deleted"],
} as const;

export const BridleTextPartDtoSchema = {
type: "object",
properties: {
Expand Down
39 changes: 38 additions & 1 deletion app/slices/setup/api/data/repositories/api/sdk.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ import type {
AddKnowledgeSourceData,
AddKnowledgeSourcesFromSitemapData,
AddKnowledgeSourcesFromSitemapResponse,
AddKnowledgeSourcesFromArchiveData,
AddKnowledgeSourcesFromArchiveResponse,
DeleteKnowledgeSourceData,
DeleteKnowledgeSourceResponse,
AgentControllerFindAllData,
Expand All @@ -84,6 +86,8 @@ import type {
AgentControllerStartData,
RestartByTemplateData,
FileControllerListData,
FileControllerDeleteData,
FileControllerDeleteResponse,
FileControllerReadData,
FileControllerReadResponse,
FileControllerSaveData,
Expand Down Expand Up @@ -863,7 +867,7 @@ export class AuthService {
}

/**
* Mint a short-lived browser embed JWT for the bridle widget. Auth: API key with embed:mint scope. Owner/Admin roles are stripped from the result regardless of input.
* Mint a short-lived browser embed JWT for the bridle widget. Auth: API key with embed:mint scope. Owner/Admin roles are stripped from the result unless the key also carries embed:mint-admin — then they are kept and the TTL is capped at 7d.
*/
public static authControllerEmbedToken<ThrowOnError extends boolean = false>(
options: Options<AuthControllerEmbedTokenData, ThrowOnError>,
Expand Down Expand Up @@ -1170,6 +1174,23 @@ export class KnowledgeSourcesService {
});
}

/**
* Bulk-import sources from a zip archive
* Accepts a .zip, extracts every ingestable file (pdf, docx, xlsx, txt, html, ...), and creates one file-type source per entry. Upload runs in the background and streams each entry to S3; the response returns immediately with the detected file count. Indexing into LightRAG happens through the normal reindex flow.
*/
public static addKnowledgeSourcesFromArchive<
ThrowOnError extends boolean = false,
>(options: Options<AddKnowledgeSourcesFromArchiveData, ThrowOnError>) {
return (options.client ?? _heyApiClient).post<
AddKnowledgeSourcesFromArchiveResponse,
unknown,
ThrowOnError
>({
url: "/knowledges/{knowledgeId}/sources/from-archive",
...options,
});
}

/**
* Delete source
*/
Expand Down Expand Up @@ -1538,6 +1559,22 @@ export class FilesService {
});
}

/**
* Delete a file, or a whole folder (e.g. a skill dir) when `recursive=true`. Template-managed skills are recreated on the next restart unless detached from the template first.
*/
public static fileControllerDelete<ThrowOnError extends boolean = false>(
options: Options<FileControllerDeleteData, ThrowOnError>,
) {
return (options.client ?? _heyApiClient).delete<
FileControllerDeleteResponse,
unknown,
ThrowOnError
>({
url: "/agents/{agentId}/files/content",
...options,
});
}

/**
* Read a chunk of a file. Omit `offset`/`limit` to read the first 256 KB. Use the returned `nextOffset` to continue.
*/
Expand Down
58 changes: 56 additions & 2 deletions app/slices/setup/api/data/repositories/api/types.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ export type RegisterDto = {
};

/**
* Server filters Owner/Admin out regardless of what is passed; embed keys cannot grant platform-admin to a visitor.
* Server filters Owner/Admin out unless the presenting API key carries the embed:mint-admin scope; plain embed keys cannot grant platform-admin to a visitor.
*/
export enum UserRoleTypes {
OWNER = "Owner",
Expand All @@ -148,7 +148,7 @@ export type EmbedTokenDto = {
sub: string;
email?: string;
/**
* Server filters Owner/Admin out regardless of what is passed; embed keys cannot grant platform-admin to a visitor.
* Server filters Owner/Admin out unless the presenting API key carries the embed:mint-admin scope; plain embed keys cannot grant platform-admin to a visitor.
*/
roles?: Array<UserRoleTypes>;
/**
Expand All @@ -159,6 +159,7 @@ export type EmbedTokenDto = {

export enum ApiKeyScopeTypes {
"EMBED:MINT" = "embed:mint",
"EMBED:MINT_ADMIN" = "embed:mint-admin",
ADMIN = "admin",
}

Expand Down Expand Up @@ -240,6 +241,14 @@ export type AddFromSitemapResultDto = {
discovered: number;
};

export type AddFromArchiveResultDto = {
/**
* Number of ingestable files detected in the archive. Import runs in the background; refresh the sources list to watch them appear.
*/
detected: number;
started: boolean;
};

export type AgentPodStatusDto = {
agentId: string;
podName: string;
Expand Down Expand Up @@ -416,6 +425,13 @@ export type SaveFileDto = {
content: string;
};

export type DeleteFilesDto = {
/**
* Number of S3 objects deleted by this request.
*/
deleted: number;
};

export type BridleTextPartDto = {
type: "text" | "image" | "file";
text: string;
Expand Down Expand Up @@ -1751,6 +1767,22 @@ export type AddKnowledgeSourcesFromSitemapResponses = {
export type AddKnowledgeSourcesFromSitemapResponse =
AddKnowledgeSourcesFromSitemapResponses[keyof AddKnowledgeSourcesFromSitemapResponses];

export type AddKnowledgeSourcesFromArchiveData = {
body?: never;
path: {
knowledgeId: string;
};
query?: never;
url: "/knowledges/{knowledgeId}/sources/from-archive";
};

export type AddKnowledgeSourcesFromArchiveResponses = {
201: AddFromArchiveResultDto;
};

export type AddKnowledgeSourcesFromArchiveResponse =
AddKnowledgeSourcesFromArchiveResponses[keyof AddKnowledgeSourcesFromArchiveResponses];

export type DeleteKnowledgeSourceData = {
body?: never;
path: {
Expand Down Expand Up @@ -2017,6 +2049,28 @@ export type FileControllerListResponses = {
200: unknown;
};

export type FileControllerDeleteData = {
body?: never;
path: {
agentId: string;
};
query: {
path: string;
/**
* When true, `path` is treated as a folder and every file under it is deleted.
*/
recursive?: boolean;
};
url: "/agents/{agentId}/files/content";
};

export type FileControllerDeleteResponses = {
200: DeleteFilesDto;
};

export type FileControllerDeleteResponse =
FileControllerDeleteResponses[keyof FileControllerDeleteResponses];

export type FileControllerReadData = {
body?: never;
path: {
Expand Down
Loading
Loading