@fugood/buttress-server 2.25.0-beta.63 → 2.25.0-beta.70
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/autodiscover/index.d.ts +20 -0
- package/lib/autodiscover/sign.d.ts +10 -0
- package/lib/autodiscover/types.d.ts +32 -0
- package/lib/autodiscover/udp.d.ts +22 -0
- package/lib/cli.d.ts +3 -0
- package/lib/index.d.ts +29 -0
- package/lib/index.mjs +671 -193
- package/lib/package.d.ts +7 -0
- package/lib/routes/anthropic-messages.d.ts +55 -0
- package/lib/routes/file.d.ts +10 -0
- package/lib/routes/index.d.ts +5 -0
- package/lib/routes/info.check.d.ts +1 -0
- package/lib/routes/info.d.ts +4 -0
- package/lib/routes/llm-shared.d.ts +54 -0
- package/lib/routes/openai-compat.d.ts +17 -0
- package/lib/routes/status.d.ts +4 -0
- package/lib/services/common.d.ts +29 -0
- package/lib/services/create-llm-service.d.ts +24 -0
- package/lib/services/ggml-llm.d.ts +5 -0
- package/lib/services/ggml-stt.d.ts +26 -0
- package/lib/services/index.d.ts +39 -0
- package/lib/services/mlx-llm.d.ts +5 -0
- package/lib/services/onnx-stt.d.ts +77 -0
- package/lib/services/onnx-tts.d.ts +48 -0
- package/lib/types.d.ts +158 -0
- package/lib/utils/SessionFileManager.d.ts +16 -0
- package/lib/utils/buttressAuth.d.ts +25 -0
- package/lib/utils/config.d.ts +21 -0
- package/lib/utils/httpAuthGuard.d.ts +1 -0
- package/lib/utils/net.d.ts +6 -0
- package/lib/utils/router.d.ts +2 -0
- package/lib/utils/serialize.d.ts +2 -0
- package/lib/utils/serverCaps.d.ts +4 -0
- package/lib/utils/sessionGuard.d.ts +33 -0
- package/lib/utils/test-caps.d.ts +61 -0
- package/lib/utils/workspaceState.d.ts +21 -0
- package/package.json +6 -6
- package/lib/chunk-C7Qqr4sF.mjs +0 -2
- package/lib/index.d.mts +0 -498
package/lib/package.d.ts
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Anthropic Messages API endpoints for ggml-llm/mlx-llm (EXPERIMENTAL)
|
|
3
|
+
* Provides /anthropic-messages/v1/messages and /anthropic-messages/v1/messages/count_tokens endpoints
|
|
4
|
+
*
|
|
5
|
+
* Implementation based on llama.cpp PR #17570 and follow-up fixes:
|
|
6
|
+
* - https://github.com/ggml-org/llama.cpp/pull/17570 (initial Anthropic Messages support)
|
|
7
|
+
* - https://github.com/ggml-org/llama.cpp/pull/18551 (signature_delta + persistent block state)
|
|
8
|
+
* - https://github.com/ggml-org/llama.cpp/pull/20120 (preserve thinking blocks in conversion)
|
|
9
|
+
*
|
|
10
|
+
* Enable via TOML config: [anthropic_messages] enabled = true
|
|
11
|
+
*
|
|
12
|
+
* Note: This feature is experimental and may change in future versions.
|
|
13
|
+
*/
|
|
14
|
+
import type { EventStream, Config } from '../types';
|
|
15
|
+
/**
|
|
16
|
+
* Stream an Anthropic Messages SSE response from the backend stream.
|
|
17
|
+
*
|
|
18
|
+
* Anthropic SSE event sequence:
|
|
19
|
+
* message_start
|
|
20
|
+
* [content_block_start (thinking)] if reasoning observed
|
|
21
|
+
* content_block_delta (thinking_delta) ...
|
|
22
|
+
* content_block_delta (signature_delta)
|
|
23
|
+
* content_block_stop
|
|
24
|
+
* [content_block_start (text)] if text observed
|
|
25
|
+
* content_block_delta (text_delta) ...
|
|
26
|
+
* content_block_stop
|
|
27
|
+
* [content_block_start (tool_use)] * for each tool call
|
|
28
|
+
* content_block_delta (input_json_delta) ...
|
|
29
|
+
* content_block_stop
|
|
30
|
+
* message_delta (stop_reason + usage)
|
|
31
|
+
* message_stop
|
|
32
|
+
*/
|
|
33
|
+
export declare function streamAnthropicMessage(completionStream: ReadableStream<EventStream>, messageId: string, modelId: string): AsyncGenerator<{
|
|
34
|
+
readonly event: "content_block_start";
|
|
35
|
+
readonly data: string;
|
|
36
|
+
} | {
|
|
37
|
+
readonly event: "content_block_delta";
|
|
38
|
+
readonly data: string;
|
|
39
|
+
} | {
|
|
40
|
+
readonly event: "message_start";
|
|
41
|
+
readonly data: string;
|
|
42
|
+
} | {
|
|
43
|
+
readonly event: "error";
|
|
44
|
+
readonly data: string;
|
|
45
|
+
} | {
|
|
46
|
+
readonly event: "content_block_stop";
|
|
47
|
+
readonly data: string;
|
|
48
|
+
} | {
|
|
49
|
+
readonly event: "message_delta";
|
|
50
|
+
readonly data: string;
|
|
51
|
+
} | {
|
|
52
|
+
readonly event: "message_stop";
|
|
53
|
+
readonly data: string;
|
|
54
|
+
}, void, unknown>;
|
|
55
|
+
export default function factory({ global: globalConfig }: Config): import("../types").ButtressApp;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
declare const _default: import("elysia").default<any, import("elysia").SingletonBase & {
|
|
2
|
+
store: import("../types").State;
|
|
3
|
+
}, any, any, any, any, {
|
|
4
|
+
derive: any;
|
|
5
|
+
resolve: any;
|
|
6
|
+
schema: any;
|
|
7
|
+
standaloneSchema: any;
|
|
8
|
+
response: {} | {};
|
|
9
|
+
}>;
|
|
10
|
+
export default _default;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { default as infoFactory } from './info';
|
|
2
|
+
export { default as file } from './file';
|
|
3
|
+
export { default as status } from './status';
|
|
4
|
+
export { default as openaiCompatFactory } from './openai-compat';
|
|
5
|
+
export { default as anthropicMessagesFactory } from './anthropic-messages';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared helpers for LLM-backed compatibility routes (OpenAI / Anthropic).
|
|
3
|
+
*
|
|
4
|
+
* The generator cache is module-scoped so different compatibility routes
|
|
5
|
+
* (e.g. /oai-compat and /anthropic-messages) reuse the same warm generator
|
|
6
|
+
* for a given model instead of duplicating contexts.
|
|
7
|
+
*/
|
|
8
|
+
export declare const LLM_TYPES: string[];
|
|
9
|
+
export type GeneratorCacheEntry = {
|
|
10
|
+
id: string;
|
|
11
|
+
type: string;
|
|
12
|
+
config: any;
|
|
13
|
+
repoId: string;
|
|
14
|
+
initialized: boolean;
|
|
15
|
+
activeRequests: number;
|
|
16
|
+
};
|
|
17
|
+
export declare function cancelReaderBestEffort(reader: {
|
|
18
|
+
cancel: () => Promise<unknown>;
|
|
19
|
+
}): void;
|
|
20
|
+
export declare function releaseGenerator(backend: any, entry: GeneratorCacheEntry | null | undefined, logPrefix?: string): Promise<void>;
|
|
21
|
+
/**
|
|
22
|
+
* Get the LLM backend API for a generator type.
|
|
23
|
+
*/
|
|
24
|
+
export declare function getLlmBackend(backend: any, type: string): any;
|
|
25
|
+
/**
|
|
26
|
+
* Get or create a cached generator for the requested model.
|
|
27
|
+
*
|
|
28
|
+
* If `requestedModel` matches a configured generator's `model.repo_id`,
|
|
29
|
+
* that config is used; otherwise the first LLM generator is selected and
|
|
30
|
+
* its repo_id is overridden with the requested model.
|
|
31
|
+
*/
|
|
32
|
+
export declare function getOrCreateGenerator(backend: any, config: any, requestedModel?: string, logPrefix?: string): Promise<GeneratorCacheEntry>;
|
|
33
|
+
/**
|
|
34
|
+
* Extract token counts from a backend completion result event.
|
|
35
|
+
*
|
|
36
|
+
* The buttress backend reports counts under `timings.prompt_n`,
|
|
37
|
+
* `timings.cache_n`, and `timings.predicted_n` (with `tokens_evaluated`
|
|
38
|
+
* historically mirroring predicted_n on the result root). We tolerate
|
|
39
|
+
* the legacy `prompt_tokens`/`tokens_predicted` field names too in case
|
|
40
|
+
* a future backend variant promotes them to the root.
|
|
41
|
+
*/
|
|
42
|
+
export declare function extractTokenCounts(eventData: Record<string, any>): {
|
|
43
|
+
promptTokens: number;
|
|
44
|
+
cachedTokens: number;
|
|
45
|
+
completionTokens: number;
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Extract token usage in OpenAI format from backend event data.
|
|
49
|
+
*/
|
|
50
|
+
export declare function extractUsage(eventData: Record<string, any>): {
|
|
51
|
+
prompt_tokens: number;
|
|
52
|
+
completion_tokens: number;
|
|
53
|
+
total_tokens: number;
|
|
54
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAI-compatible API endpoints for ggml-llm (EXPERIMENTAL)
|
|
3
|
+
* Provides /oai-compat/v1/chat/completions and /oai-compat/v1/models endpoints
|
|
4
|
+
*
|
|
5
|
+
* Enable via TOML config: [openai_compat] enabled = true
|
|
6
|
+
*
|
|
7
|
+
* Note: This feature is experimental and may change in future versions.
|
|
8
|
+
*/
|
|
9
|
+
import type { EventStream, Config } from '../types';
|
|
10
|
+
/**
|
|
11
|
+
* Stream an OpenAI-compatible chat completion (SSE) from the backend stream.
|
|
12
|
+
* Mirrors collectChatCompletion (the non-streaming path).
|
|
13
|
+
*/
|
|
14
|
+
export declare function streamChatCompletion(completionStream: ReadableStream<EventStream>, completionId: string, created: number, modelId: string, includeUsage: boolean): AsyncGenerator<{
|
|
15
|
+
readonly data: string;
|
|
16
|
+
}, void, unknown>;
|
|
17
|
+
export default function factory({ global: globalConfig }: Config): import("../types").ButtressApp;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import type { ServiceContext } from '../types';
|
|
3
|
+
export declare const schemas: {
|
|
4
|
+
getCapabilities: z.ZodTuple<[z.ZodOptional<z.ZodNullable<z.ZodObject<{
|
|
5
|
+
type: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
6
|
+
config: z.ZodOptional<z.ZodAny>;
|
|
7
|
+
currentClientCapabilities: z.ZodOptional<z.ZodAny>;
|
|
8
|
+
options: z.ZodOptional<z.ZodAny>;
|
|
9
|
+
}, "strip", z.ZodTypeAny, {
|
|
10
|
+
type: string;
|
|
11
|
+
config?: any;
|
|
12
|
+
currentClientCapabilities?: any;
|
|
13
|
+
options?: any;
|
|
14
|
+
}, {
|
|
15
|
+
type?: string | undefined;
|
|
16
|
+
config?: any;
|
|
17
|
+
currentClientCapabilities?: any;
|
|
18
|
+
options?: any;
|
|
19
|
+
}>>>], null>;
|
|
20
|
+
startGenerator: z.ZodTuple<[z.ZodString, z.ZodOptional<z.ZodAny>], null>;
|
|
21
|
+
finalizeGenerator: z.ZodTuple<[z.ZodString], null>;
|
|
22
|
+
};
|
|
23
|
+
export interface Service {
|
|
24
|
+
getCapabilities: (ctx: ServiceContext, ...args: z.infer<typeof schemas.getCapabilities>) => Promise<any>;
|
|
25
|
+
startGenerator: (ctx: ServiceContext, ...args: z.infer<typeof schemas.startGenerator>) => Promise<any>;
|
|
26
|
+
finalizeGenerator: (ctx: ServiceContext, ...args: z.infer<typeof schemas.finalizeGenerator>) => Promise<any>;
|
|
27
|
+
}
|
|
28
|
+
declare const _default: Service;
|
|
29
|
+
export default _default;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { ReadableStream } from 'node:stream/web';
|
|
3
|
+
import type { ServiceContext, EventStream, Expand } from '../types';
|
|
4
|
+
export declare const schemas: {
|
|
5
|
+
initContext: z.ZodTuple<[z.ZodString, z.ZodOptional<z.ZodAny>], null>;
|
|
6
|
+
completion: z.ZodTuple<[z.ZodString, z.ZodOptional<z.ZodAny>], null>;
|
|
7
|
+
tokenize: z.ZodTuple<[z.ZodString, z.ZodAny], null>;
|
|
8
|
+
detokenize: z.ZodTuple<[z.ZodString, z.ZodAny], null>;
|
|
9
|
+
applyChatTemplate: z.ZodTuple<[z.ZodString, z.ZodAny], null>;
|
|
10
|
+
releaseContext: z.ZodTuple<[z.ZodString], null>;
|
|
11
|
+
};
|
|
12
|
+
export interface Service {
|
|
13
|
+
initContext: (ctx: ServiceContext, ...args: z.infer<typeof schemas.initContext>) => ReadableStream<Expand<EventStream>>;
|
|
14
|
+
completion: (ctx: ServiceContext, ...args: z.infer<typeof schemas.completion>) => Promise<ReadableStream<Expand<EventStream>>>;
|
|
15
|
+
tokenize: (ctx: ServiceContext, ...args: z.infer<typeof schemas.tokenize>) => Promise<any>;
|
|
16
|
+
detokenize: (ctx: ServiceContext, ...args: z.infer<typeof schemas.detokenize>) => Promise<any>;
|
|
17
|
+
applyChatTemplate: (ctx: ServiceContext, ...args: z.infer<typeof schemas.applyChatTemplate>) => Promise<any>;
|
|
18
|
+
releaseContext: (ctx: ServiceContext, ...args: z.infer<typeof schemas.releaseContext>) => Promise<any>;
|
|
19
|
+
}
|
|
20
|
+
type GetBackend = (backend: any) => any;
|
|
21
|
+
export declare function createInitContext(getBackend: GetBackend): ({ backend, session }: ServiceContext, id: any, property: any) => ReadableStream<EventStream>;
|
|
22
|
+
export declare function createReleaseContext(getBackend: GetBackend, label: string): ({ backend, session }: ServiceContext, id: any, force: any) => Promise<any>;
|
|
23
|
+
export default function createLlmService(getBackend: GetBackend, label: string): Service;
|
|
24
|
+
export {};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import type { ServiceContext, EventStream, Expand } from '../types';
|
|
3
|
+
export declare const schemas: {
|
|
4
|
+
initContext: z.ZodTuple<[z.ZodString, z.ZodOptional<z.ZodAny>], null>;
|
|
5
|
+
transcribe: z.ZodTuple<[z.ZodString, z.ZodString, z.ZodOptional<z.ZodAny>], null>;
|
|
6
|
+
transcribeData: z.ZodTuple<[z.ZodString, z.ZodUnion<[z.ZodType<Buffer<ArrayBufferLike>, z.ZodTypeDef, Buffer<ArrayBufferLike>>, z.ZodType<Uint8Array<ArrayBuffer>, z.ZodTypeDef, Uint8Array<ArrayBuffer>>]>, z.ZodOptional<z.ZodAny>], null>;
|
|
7
|
+
releaseContext: z.ZodTuple<[z.ZodString], null>;
|
|
8
|
+
};
|
|
9
|
+
export interface Service {
|
|
10
|
+
initContext: (ctx: ServiceContext, ...args: z.infer<typeof schemas.initContext>) => ReadableStream<Expand<EventStream>>;
|
|
11
|
+
transcribe: (ctx: ServiceContext, ...args: z.infer<typeof schemas.transcribe>) => Promise<any>;
|
|
12
|
+
transcribeData: (ctx: ServiceContext, ...args: z.infer<typeof schemas.transcribeData>) => Promise<any>;
|
|
13
|
+
releaseContext: (ctx: ServiceContext, ...args: z.infer<typeof schemas.releaseContext>) => Promise<any>;
|
|
14
|
+
}
|
|
15
|
+
declare const _default: {
|
|
16
|
+
initContext: ({ backend, session }: ServiceContext, id: any, property: any) => import("stream/web").ReadableStream<EventStream>;
|
|
17
|
+
transcribe({ backend, session }: {
|
|
18
|
+
backend: any;
|
|
19
|
+
session: any;
|
|
20
|
+
}, id: any, audioPath: any, options: any): Promise<any>;
|
|
21
|
+
transcribeData({ backend }: {
|
|
22
|
+
backend: any;
|
|
23
|
+
}, id: any, audioData: any, options: any): Promise<any>;
|
|
24
|
+
releaseContext: ({ backend, session }: ServiceContext, id: any, force: any) => Promise<any>;
|
|
25
|
+
};
|
|
26
|
+
export default _default;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { ServiceContext } from '../types';
|
|
2
|
+
import type { Service as CommonService } from './common';
|
|
3
|
+
import type { Service as GgmlLlmService } from './ggml-llm';
|
|
4
|
+
import type { Service as GgmlSttService } from './ggml-stt';
|
|
5
|
+
import type { Service as MlxLlmService } from './mlx-llm';
|
|
6
|
+
import type { Service as OnnxSttService } from './onnx-stt';
|
|
7
|
+
import type { Service as OnnxTtsService } from './onnx-tts';
|
|
8
|
+
declare const services: {
|
|
9
|
+
common: CommonService;
|
|
10
|
+
ggmlLlm: GgmlLlmService;
|
|
11
|
+
ggmlStt: {
|
|
12
|
+
initContext: ({ backend, session }: ServiceContext, id: any, property: any) => import("stream/web").ReadableStream<import("../types").EventStream>;
|
|
13
|
+
transcribe({ backend, session }: {
|
|
14
|
+
backend: any;
|
|
15
|
+
session: any;
|
|
16
|
+
}, id: any, audioPath: any, options: any): Promise<any>;
|
|
17
|
+
transcribeData({ backend }: {
|
|
18
|
+
backend: any;
|
|
19
|
+
}, id: any, audioData: any, options: any): Promise<any>;
|
|
20
|
+
releaseContext: ({ backend, session }: ServiceContext, id: any, force: any) => Promise<any>;
|
|
21
|
+
};
|
|
22
|
+
mlxLlm: GgmlLlmService;
|
|
23
|
+
onnxStt: OnnxSttService;
|
|
24
|
+
onnxTts: OnnxTtsService;
|
|
25
|
+
};
|
|
26
|
+
export declare const schemas: Record<string, Record<string, any>>;
|
|
27
|
+
export type StripContext<T> = T extends (ctx: ServiceContext, ...args: infer P) => infer R ? (...args: P) => R : T;
|
|
28
|
+
export type ClientService<S> = {
|
|
29
|
+
[K in keyof S]: StripContext<S[K]>;
|
|
30
|
+
};
|
|
31
|
+
export type Services = {
|
|
32
|
+
common: ClientService<CommonService>;
|
|
33
|
+
ggmlLlm: ClientService<GgmlLlmService>;
|
|
34
|
+
ggmlStt: ClientService<GgmlSttService>;
|
|
35
|
+
mlxLlm: ClientService<MlxLlmService>;
|
|
36
|
+
onnxStt: ClientService<OnnxSttService>;
|
|
37
|
+
onnxTts: ClientService<OnnxTtsService>;
|
|
38
|
+
};
|
|
39
|
+
export default services;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { ReadableStream } from 'node:stream/web';
|
|
3
|
+
import type { ServiceContext, EventStream, Expand } from '../types';
|
|
4
|
+
export declare const schemas: {
|
|
5
|
+
initContext: z.ZodTuple<[z.ZodString, z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>], null>;
|
|
6
|
+
transcribe: z.ZodTuple<[z.ZodString, z.ZodObject<{
|
|
7
|
+
audio: z.ZodString;
|
|
8
|
+
options: z.ZodOptional<z.ZodObject<{
|
|
9
|
+
language: z.ZodOptional<z.ZodString>;
|
|
10
|
+
task: z.ZodOptional<z.ZodString>;
|
|
11
|
+
return_timestamps: z.ZodOptional<z.ZodUnion<[z.ZodBoolean, z.ZodLiteral<"word">]>>;
|
|
12
|
+
chunk_length_s: z.ZodOptional<z.ZodNumber>;
|
|
13
|
+
}, "passthrough", z.ZodTypeAny, z.objectOutputType<{
|
|
14
|
+
language: z.ZodOptional<z.ZodString>;
|
|
15
|
+
task: z.ZodOptional<z.ZodString>;
|
|
16
|
+
return_timestamps: z.ZodOptional<z.ZodUnion<[z.ZodBoolean, z.ZodLiteral<"word">]>>;
|
|
17
|
+
chunk_length_s: z.ZodOptional<z.ZodNumber>;
|
|
18
|
+
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{
|
|
19
|
+
language: z.ZodOptional<z.ZodString>;
|
|
20
|
+
task: z.ZodOptional<z.ZodString>;
|
|
21
|
+
return_timestamps: z.ZodOptional<z.ZodUnion<[z.ZodBoolean, z.ZodLiteral<"word">]>>;
|
|
22
|
+
chunk_length_s: z.ZodOptional<z.ZodNumber>;
|
|
23
|
+
}, z.ZodTypeAny, "passthrough">>>;
|
|
24
|
+
}, "strip", z.ZodTypeAny, {
|
|
25
|
+
audio: string;
|
|
26
|
+
options?: z.objectOutputType<{
|
|
27
|
+
language: z.ZodOptional<z.ZodString>;
|
|
28
|
+
task: z.ZodOptional<z.ZodString>;
|
|
29
|
+
return_timestamps: z.ZodOptional<z.ZodUnion<[z.ZodBoolean, z.ZodLiteral<"word">]>>;
|
|
30
|
+
chunk_length_s: z.ZodOptional<z.ZodNumber>;
|
|
31
|
+
}, z.ZodTypeAny, "passthrough"> | undefined;
|
|
32
|
+
}, {
|
|
33
|
+
audio: string;
|
|
34
|
+
options?: z.objectInputType<{
|
|
35
|
+
language: z.ZodOptional<z.ZodString>;
|
|
36
|
+
task: z.ZodOptional<z.ZodString>;
|
|
37
|
+
return_timestamps: z.ZodOptional<z.ZodUnion<[z.ZodBoolean, z.ZodLiteral<"word">]>>;
|
|
38
|
+
chunk_length_s: z.ZodOptional<z.ZodNumber>;
|
|
39
|
+
}, z.ZodTypeAny, "passthrough"> | undefined;
|
|
40
|
+
}>], null>;
|
|
41
|
+
transcribeData: z.ZodTuple<[z.ZodString, z.ZodUnion<[z.ZodType<Buffer<ArrayBufferLike>, z.ZodTypeDef, Buffer<ArrayBufferLike>>, z.ZodType<Uint8Array<ArrayBuffer>, z.ZodTypeDef, Uint8Array<ArrayBuffer>>]>, z.ZodOptional<z.ZodObject<{
|
|
42
|
+
language: z.ZodOptional<z.ZodString>;
|
|
43
|
+
task: z.ZodOptional<z.ZodString>;
|
|
44
|
+
return_timestamps: z.ZodOptional<z.ZodUnion<[z.ZodBoolean, z.ZodLiteral<"word">]>>;
|
|
45
|
+
chunk_length_s: z.ZodOptional<z.ZodNumber>;
|
|
46
|
+
}, "passthrough", z.ZodTypeAny, z.objectOutputType<{
|
|
47
|
+
language: z.ZodOptional<z.ZodString>;
|
|
48
|
+
task: z.ZodOptional<z.ZodString>;
|
|
49
|
+
return_timestamps: z.ZodOptional<z.ZodUnion<[z.ZodBoolean, z.ZodLiteral<"word">]>>;
|
|
50
|
+
chunk_length_s: z.ZodOptional<z.ZodNumber>;
|
|
51
|
+
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{
|
|
52
|
+
language: z.ZodOptional<z.ZodString>;
|
|
53
|
+
task: z.ZodOptional<z.ZodString>;
|
|
54
|
+
return_timestamps: z.ZodOptional<z.ZodUnion<[z.ZodBoolean, z.ZodLiteral<"word">]>>;
|
|
55
|
+
chunk_length_s: z.ZodOptional<z.ZodNumber>;
|
|
56
|
+
}, z.ZodTypeAny, "passthrough">>>], null>;
|
|
57
|
+
releaseContext: z.ZodTuple<[z.ZodString], null>;
|
|
58
|
+
};
|
|
59
|
+
export interface TranscribeResult {
|
|
60
|
+
text: string;
|
|
61
|
+
chunks?: {
|
|
62
|
+
text: string;
|
|
63
|
+
timestamp?: [number, number | null];
|
|
64
|
+
}[];
|
|
65
|
+
segments?: unknown[];
|
|
66
|
+
}
|
|
67
|
+
export interface Service {
|
|
68
|
+
initContext: (ctx: ServiceContext, ...args: z.infer<typeof schemas.initContext>) => ReadableStream<Expand<EventStream>>;
|
|
69
|
+
transcribe: (ctx: ServiceContext, ...args: z.infer<typeof schemas.transcribe>) => ReadableStream<Expand<EventStream>>;
|
|
70
|
+
transcribeData: (ctx: ServiceContext, ...args: z.infer<typeof schemas.transcribeData>) => Promise<TranscribeResult>;
|
|
71
|
+
releaseContext: (ctx: ServiceContext, ...args: z.infer<typeof schemas.releaseContext>) => Promise<{
|
|
72
|
+
released: boolean;
|
|
73
|
+
alreadyReleased?: boolean;
|
|
74
|
+
}>;
|
|
75
|
+
}
|
|
76
|
+
declare const _default: Service;
|
|
77
|
+
export default _default;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { ReadableStream } from 'node:stream/web';
|
|
3
|
+
import type { ServiceContext, EventStream, Expand } from '../types';
|
|
4
|
+
export declare const schemas: {
|
|
5
|
+
initContext: z.ZodTuple<[z.ZodString, z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>], null>;
|
|
6
|
+
addSpeaker: z.ZodTuple<[z.ZodString, z.ZodUnion<[z.ZodType<Float32Array<ArrayBuffer>, z.ZodTypeDef, Float32Array<ArrayBuffer>>, z.ZodRecord<z.ZodString, z.ZodUnknown>]>], null>;
|
|
7
|
+
synthesize: z.ZodTuple<[z.ZodString, z.ZodObject<{
|
|
8
|
+
text: z.ZodString;
|
|
9
|
+
options: z.ZodOptional<z.ZodObject<{
|
|
10
|
+
speaker: z.ZodOptional<z.ZodString>;
|
|
11
|
+
}, "passthrough", z.ZodTypeAny, z.objectOutputType<{
|
|
12
|
+
speaker: z.ZodOptional<z.ZodString>;
|
|
13
|
+
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{
|
|
14
|
+
speaker: z.ZodOptional<z.ZodString>;
|
|
15
|
+
}, z.ZodTypeAny, "passthrough">>>;
|
|
16
|
+
}, "strip", z.ZodTypeAny, {
|
|
17
|
+
text: string;
|
|
18
|
+
options?: z.objectOutputType<{
|
|
19
|
+
speaker: z.ZodOptional<z.ZodString>;
|
|
20
|
+
}, z.ZodTypeAny, "passthrough"> | undefined;
|
|
21
|
+
}, {
|
|
22
|
+
text: string;
|
|
23
|
+
options?: z.objectInputType<{
|
|
24
|
+
speaker: z.ZodOptional<z.ZodString>;
|
|
25
|
+
}, z.ZodTypeAny, "passthrough"> | undefined;
|
|
26
|
+
}>], null>;
|
|
27
|
+
releaseContext: z.ZodTuple<[z.ZodString], null>;
|
|
28
|
+
};
|
|
29
|
+
export interface AddSpeakerResult {
|
|
30
|
+
speakerId: string;
|
|
31
|
+
type: 'embed' | 'config';
|
|
32
|
+
}
|
|
33
|
+
export interface SynthesizeResult {
|
|
34
|
+
filename: string;
|
|
35
|
+
sampling_rate: number;
|
|
36
|
+
channels: number;
|
|
37
|
+
}
|
|
38
|
+
export interface Service {
|
|
39
|
+
initContext: (ctx: ServiceContext, ...args: z.infer<typeof schemas.initContext>) => ReadableStream<Expand<EventStream>>;
|
|
40
|
+
addSpeaker: (ctx: ServiceContext, ...args: z.infer<typeof schemas.addSpeaker>) => Promise<AddSpeakerResult>;
|
|
41
|
+
synthesize: (ctx: ServiceContext, ...args: z.infer<typeof schemas.synthesize>) => Promise<SynthesizeResult>;
|
|
42
|
+
releaseContext: (ctx: ServiceContext, ...args: z.infer<typeof schemas.releaseContext>) => Promise<{
|
|
43
|
+
released: boolean;
|
|
44
|
+
alreadyReleased?: boolean;
|
|
45
|
+
}>;
|
|
46
|
+
}
|
|
47
|
+
declare const _default: Service;
|
|
48
|
+
export default _default;
|
package/lib/types.d.ts
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import type { Elysia, SingletonBase } from 'elysia';
|
|
2
|
+
import type { ReadableStream } from 'node:stream/web';
|
|
3
|
+
import type { Backend } from './index';
|
|
4
|
+
export type HumanReadableUnit = number | string;
|
|
5
|
+
type NormalizeKeys = 'max_body_size' | 'session_timeout' | 'max_size_bytes';
|
|
6
|
+
export type DeepNormalize<T> = T extends object ? {
|
|
7
|
+
[K in keyof T]: K extends NormalizeKeys ? number : DeepNormalize<T[K]>;
|
|
8
|
+
} : T;
|
|
9
|
+
export type HumanReadableServerConfig = {
|
|
10
|
+
id?: string;
|
|
11
|
+
name?: string;
|
|
12
|
+
port?: number;
|
|
13
|
+
log_level?: 'debug' | 'info' | 'warn' | 'error';
|
|
14
|
+
max_body_size?: HumanReadableUnit;
|
|
15
|
+
session_timeout?: HumanReadableUnit;
|
|
16
|
+
temp_file_dir?: string;
|
|
17
|
+
};
|
|
18
|
+
export type SessionCacheConfig = {
|
|
19
|
+
enabled?: boolean;
|
|
20
|
+
max_size_bytes?: HumanReadableUnit;
|
|
21
|
+
max_entries?: number;
|
|
22
|
+
};
|
|
23
|
+
export type RuntimeConfig = {
|
|
24
|
+
cache_dir?: string;
|
|
25
|
+
huggingface_token?: string;
|
|
26
|
+
session_cache?: SessionCacheConfig;
|
|
27
|
+
} & Record<string, any>;
|
|
28
|
+
export type GeneratorType = 'ggml-llm' | 'ggml-stt' | 'mlx-llm' | 'onnx-stt' | 'onnx-tts';
|
|
29
|
+
export type GeneratorConfig = {
|
|
30
|
+
type: GeneratorType;
|
|
31
|
+
} & Record<string, any>;
|
|
32
|
+
export type GlobalConfig = {
|
|
33
|
+
runtime?: RuntimeConfig;
|
|
34
|
+
openai_compat?: {
|
|
35
|
+
enabled?: boolean;
|
|
36
|
+
cors_allowed_origins?: string | string[];
|
|
37
|
+
};
|
|
38
|
+
anthropic_messages?: {
|
|
39
|
+
enabled?: boolean;
|
|
40
|
+
cors_allowed_origins?: string | string[];
|
|
41
|
+
};
|
|
42
|
+
} & Record<string, any>;
|
|
43
|
+
export type AutodiscoverConfig = {
|
|
44
|
+
udp: {
|
|
45
|
+
port?: number;
|
|
46
|
+
announcements: {
|
|
47
|
+
enabled: boolean;
|
|
48
|
+
interval?: number;
|
|
49
|
+
};
|
|
50
|
+
requests: {
|
|
51
|
+
enabled: boolean;
|
|
52
|
+
responseDelay?: number;
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
http: {
|
|
56
|
+
enabled: boolean;
|
|
57
|
+
path?: string;
|
|
58
|
+
cors?: boolean;
|
|
59
|
+
};
|
|
60
|
+
mdns?: {
|
|
61
|
+
enabled: boolean;
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
export type HumanReadableConfig = {
|
|
65
|
+
autodiscover?: AutodiscoverConfig | boolean;
|
|
66
|
+
server?: HumanReadableServerConfig;
|
|
67
|
+
generators?: GeneratorConfig[];
|
|
68
|
+
} & GlobalConfig;
|
|
69
|
+
export type ServerConfig = {
|
|
70
|
+
id: string;
|
|
71
|
+
name: string;
|
|
72
|
+
port: number;
|
|
73
|
+
log_level?: 'debug' | 'info' | 'warn' | 'error';
|
|
74
|
+
max_body_size: number;
|
|
75
|
+
session_timeout: number;
|
|
76
|
+
temp_file_dir: string;
|
|
77
|
+
};
|
|
78
|
+
export type Config = {
|
|
79
|
+
autodiscover: AutodiscoverConfig | null;
|
|
80
|
+
server: ServerConfig;
|
|
81
|
+
global: GlobalConfig;
|
|
82
|
+
generators: GeneratorConfig[];
|
|
83
|
+
};
|
|
84
|
+
export type GeneratorInfo = {
|
|
85
|
+
type: GeneratorType;
|
|
86
|
+
/** Performance score 0–100 from buttress-hardware-guardrails. */
|
|
87
|
+
score?: number;
|
|
88
|
+
/** Whether the host has an accelerator (GPU/Metal/etc) for this backend. */
|
|
89
|
+
hasGpu?: boolean;
|
|
90
|
+
/** Usable memory in bytes for this backend (GPU when present, else CPU). */
|
|
91
|
+
usableBytes?: number;
|
|
92
|
+
} & Record<string, any>;
|
|
93
|
+
export type ServerInfo = {
|
|
94
|
+
id: string;
|
|
95
|
+
name: string;
|
|
96
|
+
version: string;
|
|
97
|
+
address: string;
|
|
98
|
+
addresses?: string[];
|
|
99
|
+
port: number;
|
|
100
|
+
url: string;
|
|
101
|
+
generators: GeneratorInfo[];
|
|
102
|
+
authentication: {
|
|
103
|
+
required: boolean;
|
|
104
|
+
type: string;
|
|
105
|
+
/** Issuer key id (when type === 'workspace-jwt'). */
|
|
106
|
+
kid?: string;
|
|
107
|
+
/** True when buttress is paired with a workspace. */
|
|
108
|
+
bound?: boolean;
|
|
109
|
+
};
|
|
110
|
+
/** Workspace identity (only present when paired). */
|
|
111
|
+
workspace?: {
|
|
112
|
+
id: string;
|
|
113
|
+
name?: string;
|
|
114
|
+
};
|
|
115
|
+
};
|
|
116
|
+
export type EventStream = {
|
|
117
|
+
event: string;
|
|
118
|
+
data: any;
|
|
119
|
+
};
|
|
120
|
+
export type StreamReaderEntry = {
|
|
121
|
+
reader: ReadableStreamDefaultReader<EventStream>;
|
|
122
|
+
peerId: string;
|
|
123
|
+
};
|
|
124
|
+
export type Session = {
|
|
125
|
+
streams: Map<string, ReadableStream<EventStream>>;
|
|
126
|
+
streamReaders: Map<string, StreamReaderEntry>;
|
|
127
|
+
generators: Set<string>;
|
|
128
|
+
fileManager: import('./utils/SessionFileManager').SessionFileManager;
|
|
129
|
+
initializedContexts: Set<string>;
|
|
130
|
+
timeout: ReturnType<typeof setTimeout> | null;
|
|
131
|
+
identity?: import('./utils/buttressAuth').VerifiedIdentity | null;
|
|
132
|
+
ready?: Promise<boolean>;
|
|
133
|
+
currentPeerId?: string | null;
|
|
134
|
+
};
|
|
135
|
+
export type State = {
|
|
136
|
+
serverInfo: ServerInfo;
|
|
137
|
+
backend: Backend;
|
|
138
|
+
config: Config;
|
|
139
|
+
sessions: Map<string, Session>;
|
|
140
|
+
workspaceState: import('./utils/workspaceState').WorkspaceState;
|
|
141
|
+
};
|
|
142
|
+
type ButtressSingleton = SingletonBase & {
|
|
143
|
+
store: State;
|
|
144
|
+
};
|
|
145
|
+
export type ButtressApp = Elysia<any, ButtressSingleton, any, any, any, any, any>;
|
|
146
|
+
export type MethodReturnType = string | object | number | boolean | null | ReadableStream<EventStream>;
|
|
147
|
+
export type ServiceContext = State & {
|
|
148
|
+
peerId: string;
|
|
149
|
+
session: Session;
|
|
150
|
+
};
|
|
151
|
+
export type ServiceMethodHandler<InputType = any, OutputType = any> = (ctx: ServiceContext, property: InputType) => OutputType | Promise<OutputType>;
|
|
152
|
+
export interface ServiceHandler {
|
|
153
|
+
[method: string]: ServiceMethodHandler;
|
|
154
|
+
}
|
|
155
|
+
export type Expand<T> = T extends object ? {
|
|
156
|
+
[K in keyof T]: Expand<T[K]>;
|
|
157
|
+
} : T;
|
|
158
|
+
export {};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { ReadableStream as NodeReadableStream } from 'node:stream/web';
|
|
2
|
+
type UploadData = Buffer | ArrayBuffer | ReadableStream | NodeReadableStream;
|
|
3
|
+
export declare class SessionFileManager {
|
|
4
|
+
sessionId: string;
|
|
5
|
+
private sessionDir;
|
|
6
|
+
private registry;
|
|
7
|
+
constructor(sessionId: string, tempDir: string);
|
|
8
|
+
register(filename: string, realPath: string, opts?: {
|
|
9
|
+
owned?: boolean;
|
|
10
|
+
ttl?: number;
|
|
11
|
+
}): void;
|
|
12
|
+
resolve(filename: string): string | null;
|
|
13
|
+
storeUpload(originalName: string, data: UploadData): Promise<string>;
|
|
14
|
+
destroy(): Promise<void>;
|
|
15
|
+
}
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { WorkspaceBinding } from './workspaceState';
|
|
2
|
+
export declare const ACCESS_TOKEN_KIND = "ba";
|
|
3
|
+
export interface AccessTokenClaims {
|
|
4
|
+
k: typeof ACCESS_TOKEN_KIND;
|
|
5
|
+
w_id: string;
|
|
6
|
+
st: 'ws' | 'dev';
|
|
7
|
+
sid: string;
|
|
8
|
+
jti?: string;
|
|
9
|
+
iat?: number;
|
|
10
|
+
exp: number;
|
|
11
|
+
}
|
|
12
|
+
export interface VerifiedIdentity {
|
|
13
|
+
workspaceId: string;
|
|
14
|
+
subjectType: 'ws' | 'dev';
|
|
15
|
+
subjectId: string;
|
|
16
|
+
jti?: string;
|
|
17
|
+
exp: number;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Extract a buttress access token from a request. Prefers the Authorization
|
|
21
|
+
* Bearer header; falls back to ?access_token / ?token query params for clients
|
|
22
|
+
* (browser WebSocket, RN file transfer) that can't set headers.
|
|
23
|
+
*/
|
|
24
|
+
export declare const extractAccessTokenFromRequest: (headers: Record<string, string | undefined> | undefined, query: Record<string, unknown> | undefined) => string | null;
|
|
25
|
+
export declare const verifyAccessToken: (token: string | null, binding: WorkspaceBinding | null) => Promise<VerifiedIdentity | null>;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Config, AutodiscoverConfig, HumanReadableConfig } from '../types';
|
|
2
|
+
import type { Backend } from '../index';
|
|
3
|
+
export declare const deepMerge: (target?: Record<string, any>, source?: Record<string, any>) => Record<string, any>;
|
|
4
|
+
export declare const normalizeConfigInput: (input: any) => null | Record<string, any>;
|
|
5
|
+
export declare const mergeGeneratorConfig: (base: any, override: any) => Record<string, any>;
|
|
6
|
+
export declare const resolveDefaultConfig: (defaultConfigs: Config, backend: Backend, type: string, modelId: string | null) => Record<string, any> | null;
|
|
7
|
+
/**
|
|
8
|
+
* Normalize autodiscover config input.
|
|
9
|
+
* - undefined/false → null (disabled)
|
|
10
|
+
* - true → default config
|
|
11
|
+
* - object → merge with defaults
|
|
12
|
+
*/
|
|
13
|
+
export declare const normalizeAutodiscoverConfig: (input: AutodiscoverConfig | boolean | undefined) => AutodiscoverConfig | null;
|
|
14
|
+
export declare const resolveSupportedGenerators: (config: Config, defaultTypes: string[]) => {
|
|
15
|
+
type: string;
|
|
16
|
+
}[];
|
|
17
|
+
/**
|
|
18
|
+
* Process raw user config (HumanReadableConfig) into Config.
|
|
19
|
+
* Handles: device defaults, value normalization (bytes/ms), structure splitting.
|
|
20
|
+
*/
|
|
21
|
+
export declare const processConfig: (input: HumanReadableConfig | null) => Config;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const buttressAuthGuard: any;
|