@fugood/buttress-server 2.26.0-beta.19 → 2.26.0-beta.20
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/README.md +91 -37
- package/config/sample.toml +1 -2
- package/lib/agent/tools.d.ts +5 -2
- package/lib/{cli-CIa2rDj7.mjs → cli-KbjOekMI.mjs} +2 -2
- package/lib/{client-BVyIuSyr.mjs → client-qqI-HCOj.mjs} +1 -1
- package/lib/command-B92OGHj0.mjs +38 -0
- package/lib/config-DiYweJ2m.mjs +2 -0
- package/lib/index.mjs +61 -99
- package/lib/net-DPM9odNy.mjs +46 -0
- package/lib/routes/agents.d.ts +33 -4
- package/lib/routes/openai-compat.d.ts +13 -2
- package/lib/routes/openai-decisions.check.d.ts +1 -0
- package/lib/routes/openai-decisions.d.ts +97 -0
- package/lib/routes/status.d.ts +2 -1
- package/lib/routes/typesafe-compat.d.ts +5 -6
- package/lib/{tui-Bxeb1d7E.mjs → tui-ClNupsCH.mjs} +1 -1
- package/lib/types.d.ts +14 -2
- package/lib/ui/command.d.ts +2 -0
- package/lib/ui/host.d.ts +1 -0
- package/lib/ui/window-module.d.ts +6 -0
- package/lib/utils/config.d.ts +2 -1
- package/lib/utils/downloadStatus.d.ts +57 -0
- package/lib/utils/hostFacts.d.ts +13 -0
- package/package.json +10 -8
- package/public/status.html +219 -1592
- package/lib/config-cxApm_PZ.mjs +0 -2
package/lib/routes/agents.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Agent endpoints (EXPERIMENTAL).
|
|
3
3
|
*
|
|
4
|
-
* GET /agents configured
|
|
4
|
+
* GET /agents configured agents: names, plus details
|
|
5
|
+
* (model, tools, MCP server names, limits)
|
|
5
6
|
* POST /agents/:name/run run a prompt; ?stream=1 for SSE events
|
|
6
7
|
* (first a `session` event with the id,
|
|
7
8
|
* then `agent` events, then result/error)
|
|
@@ -18,12 +19,40 @@
|
|
|
18
19
|
* accepts workspace JWTs. The server's own ephemeral internal token (also
|
|
19
20
|
* written to the 0600 runtime file for same-host CLIs) is always accepted.
|
|
20
21
|
*/
|
|
21
|
-
import { type AgentsService } from '../agent/types';
|
|
22
|
+
import { type AgentDefinition, type AgentsService } from '../agent/types';
|
|
23
|
+
/**
|
|
24
|
+
* What a client may show about an agent. MCP servers are listed by name only:
|
|
25
|
+
* their urls, headers, commands and env can hold credentials.
|
|
26
|
+
*/
|
|
27
|
+
export declare const describeAgent: (agent: AgentDefinition) => {
|
|
28
|
+
name: string;
|
|
29
|
+
model: string;
|
|
30
|
+
tools: string[];
|
|
31
|
+
mcpServers: string[];
|
|
32
|
+
maxTurns: number;
|
|
33
|
+
localDevices: boolean;
|
|
34
|
+
codemode: boolean;
|
|
35
|
+
decisionModel: string | null;
|
|
36
|
+
};
|
|
37
|
+
export type ToolResultSummary = {
|
|
38
|
+
text: string | null;
|
|
39
|
+
images: number;
|
|
40
|
+
truncated: boolean;
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* A tool result for the wire: its text (bounded) and how many images it holds.
|
|
44
|
+
* Image bytes never go out; the transcript endpoint has the full result.
|
|
45
|
+
*
|
|
46
|
+
* pi passes the tool's own return value: normally `{ content: (text | image)[] }`,
|
|
47
|
+
* but untyped tools may return a bare string or no content at all.
|
|
48
|
+
*/
|
|
49
|
+
export declare const summarizeToolResult: (result: unknown) => ToolResultSummary;
|
|
22
50
|
/**
|
|
23
51
|
* Slim pi agent events for the wire. `message_update` carries the FULL partial
|
|
24
52
|
* assistant message on every delta — per-token that would dwarf the payload —
|
|
25
|
-
* and tool results can be huge
|
|
26
|
-
* from the sessions
|
|
53
|
+
* and tool results can be huge (`tool_execution_end` carries a bounded text
|
|
54
|
+
* summary); clients that want the full transcript fetch it from the sessions
|
|
55
|
+
* endpoint afterwards.
|
|
27
56
|
*/
|
|
28
57
|
export declare const slimAgentEvent: (event: any) => unknown;
|
|
29
58
|
export declare function streamAgentRun(agents: AgentsService, name: string, body: {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* OpenAI-compatible API endpoints for ggml-llm (EXPERIMENTAL)
|
|
3
|
-
* Provides /oai-compat/v1/chat/completions
|
|
2
|
+
* OpenAI-compatible API endpoints for ggml-llm and ggml-decision (EXPERIMENTAL)
|
|
3
|
+
* Provides /oai-compat/v1/chat/completions, /oai-compat/v1/decisions and
|
|
4
|
+
* /oai-compat/v1/models endpoints
|
|
4
5
|
*
|
|
5
6
|
* Enable via TOML config: [openai_compat] enabled = true
|
|
6
7
|
*
|
|
@@ -14,4 +15,14 @@ import type { EventStream } from '../types';
|
|
|
14
15
|
export declare function streamChatCompletion(completionStream: ReadableStream<EventStream>, completionId: string, created: number, modelId: string, includeUsage: boolean): AsyncGenerator<{
|
|
15
16
|
readonly data: string;
|
|
16
17
|
}, void, unknown>;
|
|
18
|
+
/**
|
|
19
|
+
* Model id -> what this server can do with it, from the config alone (no model
|
|
20
|
+
* load), in the `architecture` shape that llama.cpp server and OpenRouter
|
|
21
|
+
* publish: `text` output means chat completions, `decisions` means
|
|
22
|
+
* `/v1/decisions`. Clients should test membership and ignore unknown values.
|
|
23
|
+
*/
|
|
24
|
+
export declare const collectModelArchitectures: (generators: any[]) => Map<string, {
|
|
25
|
+
input_modalities: string[];
|
|
26
|
+
output_modalities: string[];
|
|
27
|
+
}>;
|
|
17
28
|
export default function factory(): import("../types").ButtressApp;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAI Decisions API (`POST /v1/decisions`) <-> native decision requests.
|
|
3
|
+
*
|
|
4
|
+
* Spec: https://developers.openai.com/api/docs/guides/decisions
|
|
5
|
+
*
|
|
6
|
+
* The native request follows the TypeSafe `/v1/systemone` contract, so the
|
|
7
|
+
* question types map one to one: `predicate` -> `noul`, `choice` -> `choice`,
|
|
8
|
+
* `score` -> `score`. What differs is the shape: OpenAI sends an ordered array
|
|
9
|
+
* of optionally named questions with typed choice values and returns an
|
|
10
|
+
* ordered array of answers; native keys questions and options by string.
|
|
11
|
+
* The local models never refuse, so no `refusal` answer is produced.
|
|
12
|
+
*/
|
|
13
|
+
import type { DecisionRequest, DecisionResult } from '../types';
|
|
14
|
+
type ChoiceValue = string | boolean;
|
|
15
|
+
type QuestionPlan = {
|
|
16
|
+
id: string;
|
|
17
|
+
name: string | null;
|
|
18
|
+
type: 'predicate';
|
|
19
|
+
} | {
|
|
20
|
+
id: string;
|
|
21
|
+
name: string | null;
|
|
22
|
+
type: 'choice';
|
|
23
|
+
options: {
|
|
24
|
+
key: string;
|
|
25
|
+
value: ChoiceValue;
|
|
26
|
+
}[];
|
|
27
|
+
} | {
|
|
28
|
+
id: string;
|
|
29
|
+
name: string | null;
|
|
30
|
+
type: 'score';
|
|
31
|
+
labels: string[];
|
|
32
|
+
};
|
|
33
|
+
export type DecisionPlan = {
|
|
34
|
+
questions: QuestionPlan[];
|
|
35
|
+
};
|
|
36
|
+
export declare class DecisionRequestError extends Error {
|
|
37
|
+
param: string | null;
|
|
38
|
+
constructor(param: string | null, message: string);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Validate an OpenAI decision request and convert it to the native one.
|
|
42
|
+
* Throws a DecisionRequestError naming the offending field.
|
|
43
|
+
*/
|
|
44
|
+
export declare const toNativeDecisionRequest: (body: unknown) => {
|
|
45
|
+
model: string;
|
|
46
|
+
request: DecisionRequest;
|
|
47
|
+
plan: DecisionPlan;
|
|
48
|
+
};
|
|
49
|
+
/** Convert a native result to an OpenAI `Decision` object, answers in request order. */
|
|
50
|
+
export declare const toOpenAIDecision: (result: DecisionResult, plan: DecisionPlan, model: string) => {
|
|
51
|
+
model: string;
|
|
52
|
+
answers: ({
|
|
53
|
+
type: string;
|
|
54
|
+
name: string | null;
|
|
55
|
+
probability: number;
|
|
56
|
+
choice?: undefined;
|
|
57
|
+
score?: undefined;
|
|
58
|
+
probabilities?: undefined;
|
|
59
|
+
confidence?: undefined;
|
|
60
|
+
} | {
|
|
61
|
+
probability?: undefined;
|
|
62
|
+
type: string;
|
|
63
|
+
name: string | null;
|
|
64
|
+
choice: any;
|
|
65
|
+
probabilities: {
|
|
66
|
+
value: ChoiceValue;
|
|
67
|
+
probability: number;
|
|
68
|
+
}[];
|
|
69
|
+
confidence: number;
|
|
70
|
+
score?: undefined;
|
|
71
|
+
} | {
|
|
72
|
+
probability?: undefined;
|
|
73
|
+
choice?: undefined;
|
|
74
|
+
type: string;
|
|
75
|
+
name: string | null;
|
|
76
|
+
score: number;
|
|
77
|
+
probabilities: {
|
|
78
|
+
value: number;
|
|
79
|
+
label: string;
|
|
80
|
+
probability: number;
|
|
81
|
+
}[];
|
|
82
|
+
confidence: number;
|
|
83
|
+
})[];
|
|
84
|
+
usage: {
|
|
85
|
+
input_tokens: number;
|
|
86
|
+
input_tokens_details: {
|
|
87
|
+
cached_tokens: number;
|
|
88
|
+
cache_write_tokens: number;
|
|
89
|
+
};
|
|
90
|
+
output_tokens: number;
|
|
91
|
+
output_tokens_details: {
|
|
92
|
+
reasoning_tokens: number;
|
|
93
|
+
};
|
|
94
|
+
total_tokens: number;
|
|
95
|
+
};
|
|
96
|
+
};
|
|
97
|
+
export {};
|
package/lib/routes/status.d.ts
CHANGED
|
@@ -9,10 +9,9 @@
|
|
|
9
9
|
*
|
|
10
10
|
* Enable via TOML config: [typesafe_compat] enabled = true
|
|
11
11
|
*
|
|
12
|
-
* `model` selects a configured decision generator by its published id
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* model answers with different calibration, which the caller cannot detect.
|
|
12
|
+
* `model` selects a configured decision generator by its published id. An
|
|
13
|
+
* unknown model is rejected, never substituted: another model answers with
|
|
14
|
+
* different calibration, which the caller cannot detect.
|
|
16
15
|
*/
|
|
17
16
|
type ValidationIssue = {
|
|
18
17
|
loc: (string | number)[];
|
|
@@ -25,7 +24,7 @@ type ValidationIssue = {
|
|
|
25
24
|
* precisely, with the field location the SDKs print.
|
|
26
25
|
*/
|
|
27
26
|
export declare const validateSystemOneRequest: (body: any) => ValidationIssue[];
|
|
28
|
-
/** Published
|
|
29
|
-
export declare const
|
|
27
|
+
/** Published ids of the configured decision generators, in config order. */
|
|
28
|
+
export declare const decisionModelIds: (config: any) => string[];
|
|
30
29
|
export default function factory(): import("../types").ButtressApp;
|
|
31
30
|
export {};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{a as e,t}from"./client-
|
|
2
|
+
import{a as e,t}from"./client-qqI-HCOj.mjs";import{Container as n,Editor as r,Loader as i,Markdown as a,ProcessTerminal as o,Text as s,TuiMainScreen as c}from"@earendil-works/pi-tui";const l=e=>t=>`\x1b[${e}m${t}\x1b[0m`,u=l(`2`),d=l(`1`),f=l(`36`),p=l(`33`),m=l(`31`),h=l(`32`),g=l(`35`),_={heading:e=>d(f(e)),link:f,linkUrl:e=>u(f(e)),code:p,codeBlock:p,codeBlockBorder:u,quote:u,quoteBorder:u,hr:u,listBullet:f,bold:d,italic:l(`3`),strikethrough:l(`9`),underline:l(`4`)},v={borderColor:u,selectList:{selectedPrefix:f,selectedText:d,description:u,scrollInfo:u,noMatch:u}},y=(e,t)=>e.length>t?`${e.slice(0,t)}…`:e;var b=class{tui;chat;thinking=null;thinkingBuffer=``;answer=null;answerBuffer=``;constructor(e,t){this.tui=e,this.chat=t}touch(){this.tui.requestRender()}appendThinking(e){this.thinking||(this.thinking=new s(``,0,0),this.chat.addChild(this.thinking)),this.thinkingBuffer+=e,this.thinking.setText(u(this.thinkingBuffer.trimEnd())),this.touch()}appendAnswer(e){this.answer||(this.answer=new a(``,0,0,_),this.chat.addChild(this.answer)),this.answerBuffer+=e,this.answer.setText(this.answerBuffer),this.touch()}addLine(e){this.answer=null,this.answerBuffer=``,this.chat.addChild(new s(e,0,0)),this.touch()}};const x=async({connection:a,agentName:l,sessionId:_,fork:x})=>{let S=new o,C=new c(S);S.setTitle(`buttress agent · ${l}`);let w=new n,T=new s(``,0,0),E=new r(C,v);C.addChild(w),C.addChild(T),C.addChild(E),C.setFocus(E);let D=_,O=x,k=null,A=null,j=e=>{T.setText(e),C.requestRender()},M=()=>{A||(A=new i(C,f,u,`thinking…`),w.addChild(A),C.requestRender())},N=()=>{A&&(w.removeChild(A),A=null,C.requestRender())},P=`${d(l)} ${u(`@ ${a.baseUrl}`)}`+(D?` ${u(`(${O?`forking`:`continuing`} ${D})`)}`:``);w.addChild(new s(P,0,0)),j(u(`Enter to send · /new fresh session · /exit or Ctrl+C to quit`));let F=async()=>{C.stop(),await S.drainInput().catch(()=>{}),process.exit(0)};C.addInputListener(e=>{if(e===``)return k?(k.abort(),k=null,{consume:!0}):(F(),{consume:!0})});let I=async n=>{w.addChild(new s(`${f(`>`)} ${n}`,0,0));let r=new b(C,w),i=D;k=new AbortController,M(),j(u(`running · Ctrl+C aborts this turn`));let o;try{o=await e(a,l,{prompt:n,sessionId:D??void 0,fork:O},{signal:k.signal,onFrame:({event:e,payload:t})=>{if(e===`session`&&t?.sessionId){t.sessionId!==D&&(D=t.sessionId,w.addChild(new s(u(`session ${D}`),0,0)));return}if(e!==`agent`)return;N();let n=t?.event;if(t?.type===`message_update`&&n)n.type===`thinking_delta`?r.appendThinking(n.delta??``):n.type===`text_delta`&&r.appendAnswer(n.delta??``);else if(t?.type===`tool_execution_start`){let e=JSON.stringify(t.args??{});r.addLine(`${p(`⚙ ${t.toolName}`)}${u(`(${y(e,120)})`)}`)}else t?.type===`tool_execution_end`?r.addLine(t.isError?m(`✗ ${t.toolName} failed`):u(`✓ ${t.toolName}`)):t?.type===`tool_emit`&&r.addLine(u(` ${t.toolName} → ${t.event}`))}})}catch(e){o={kind:`error`,message:e?.message||String(e),sessionId:D}}if(N(),k=null,o.kind===`result`){let{result:e}=o;D=e.sessionId??D;let t=e.usage||{};w.addChild(new s(u(`— ${e.stopReason} · ${t.totalTurns??`?`} turn(s) · ${t.input??0} in / ${t.output??0} out · session ${D}`),0,0))}else o.kind===`aborted`?(D=o.sessionId??D,w.addChild(new s(p(`(aborted — session is continuable)`),0,0))):o.kind===`error`?(D=o.sessionId??D,w.addChild(new s(m(`Run failed: ${o.message}`),0,0))):w.addChild(new s(m(`Connection lost mid-run.`),0,0));t(i,D)&&(O=!1),j(u(`Enter to send · /new fresh session · /exit or Ctrl+C to quit`)),C.requestRender()};E.onSubmit=e=>{let t=e.trim();if(E.setText(``),t){if(k){j(p(`A turn is still running — Ctrl+C aborts it.`));return}if(t===`/exit`||t===`/quit`){F();return}if(t===`/new`){D=null,O=!1,w.addChild(new s(`${h(`•`)} ${u(`started a fresh session`)}`,0,0)),C.requestRender();return}if(t===`/session`){w.addChild(new s(u(D?`session ${D}`:`no session yet`),0,0)),C.requestRender();return}I(t)}},w.addChild(new s(u(g(`ready`)),0,0)),C.start(),await new Promise(()=>{})};export{x as runAgentTui};
|
package/lib/types.d.ts
CHANGED
|
@@ -61,8 +61,6 @@ export type GlobalConfig = {
|
|
|
61
61
|
typesafe_compat?: {
|
|
62
62
|
enabled?: boolean;
|
|
63
63
|
cors_allowed_origins?: string | string[];
|
|
64
|
-
/** Request `model` names (e.g. `jev-latest`) mapped to a decision generator id. */
|
|
65
|
-
models?: Record<string, string>;
|
|
66
64
|
};
|
|
67
65
|
functions?: {
|
|
68
66
|
enabled?: boolean;
|
|
@@ -195,6 +193,20 @@ export type State = {
|
|
|
195
193
|
config: Config;
|
|
196
194
|
sessions: Map<string, Session>;
|
|
197
195
|
workspaceState: import('./utils/workspaceState').WorkspaceState;
|
|
196
|
+
/** Epoch ms when `createServer` began, reported on `/buttress/status`. */
|
|
197
|
+
startedAt: number;
|
|
198
|
+
/** The compatibility endpoints this process serves (env var or config flag). */
|
|
199
|
+
endpoints: {
|
|
200
|
+
openaiCompat: boolean;
|
|
201
|
+
anthropicMessages: boolean;
|
|
202
|
+
typesafeCompat: boolean;
|
|
203
|
+
};
|
|
204
|
+
/** Local functions; null when the feature is off or failed to start. */
|
|
205
|
+
functionsService: import('./functions').FunctionsService | null;
|
|
206
|
+
/** Config-defined agents; null when none are configured or they failed to start. */
|
|
207
|
+
agentsService: import('./agent/types').AgentsService | null;
|
|
208
|
+
/** This machine, read once at startup for `/buttress/status`. */
|
|
209
|
+
host: import('./utils/hostFacts').HostFacts;
|
|
198
210
|
};
|
|
199
211
|
type ButtressSingleton = SingletonBase & {
|
|
200
212
|
store: State;
|
package/lib/ui/host.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { LaunchButtressUi } from '@fugood/buttress-ui/src/host';
|
|
2
|
+
export declare const UI_PACKAGE = "@fugood/buttress-ui";
|
|
3
|
+
export type WindowModule = {
|
|
4
|
+
launchButtressUi: LaunchButtressUi;
|
|
5
|
+
};
|
|
6
|
+
export declare const importWindowModule: () => Promise<WindowModule>;
|
package/lib/utils/config.d.ts
CHANGED
|
@@ -15,6 +15,7 @@ export declare const resolveSupportedGenerators: (config: Config, defaultTypes:
|
|
|
15
15
|
}[];
|
|
16
16
|
/**
|
|
17
17
|
* Process raw user config (HumanReadableConfig) into Config.
|
|
18
|
-
* Handles: device defaults, value normalization (bytes/ms), structure splitting
|
|
18
|
+
* Handles: device defaults, value normalization (bytes/ms), structure splitting,
|
|
19
|
+
* and dropping generators with `enabled = false`.
|
|
19
20
|
*/
|
|
20
21
|
export declare const processConfig: (input: HumanReadableConfig | null) => Config;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Model pre-downloads (`download = true`) for `/buttress/status`: the ones in
|
|
3
|
+
* flight plus a short newest-first history.
|
|
4
|
+
*
|
|
5
|
+
* The backends report progress as a 0–1 fraction only, so byte counts stay
|
|
6
|
+
* unknown (`receivedBytes` 0, `totalBytes` / `bytesPerSecond` null) and the
|
|
7
|
+
* fraction is exposed as `progress`. Downloads a session starts on demand go
|
|
8
|
+
* through backend-core's download manager, which tracks no metadata, so they
|
|
9
|
+
* are not listed here.
|
|
10
|
+
*
|
|
11
|
+
* A module-scoped singleton like the other status trackers: the CLI records
|
|
12
|
+
* into it and the status route snapshots it.
|
|
13
|
+
*/
|
|
14
|
+
import type { GeneratorType } from '../types';
|
|
15
|
+
export type ActiveDownload = {
|
|
16
|
+
type: GeneratorType;
|
|
17
|
+
repoId: string;
|
|
18
|
+
filename: string | null;
|
|
19
|
+
receivedBytes: number;
|
|
20
|
+
totalBytes: number | null;
|
|
21
|
+
bytesPerSecond: number | null;
|
|
22
|
+
startedAt: string;
|
|
23
|
+
/** 0–1 as reported by the backend; null before the first report. */
|
|
24
|
+
progress: number | null;
|
|
25
|
+
};
|
|
26
|
+
export type FinishedDownload = {
|
|
27
|
+
type: GeneratorType;
|
|
28
|
+
repoId: string;
|
|
29
|
+
filename: string | null;
|
|
30
|
+
totalBytes: number | null;
|
|
31
|
+
durationMs: number;
|
|
32
|
+
finishedAt: string;
|
|
33
|
+
success: boolean;
|
|
34
|
+
error?: string;
|
|
35
|
+
};
|
|
36
|
+
export type DownloadsSnapshot = {
|
|
37
|
+
active: ActiveDownload[];
|
|
38
|
+
recent: FinishedDownload[];
|
|
39
|
+
};
|
|
40
|
+
/** Feeds one download's callbacks into the tracker. Calls after the first ending are no-ops. */
|
|
41
|
+
export type DownloadHandle = {
|
|
42
|
+
progress(fraction: number): void;
|
|
43
|
+
/** Replaces the repo named at `begin` with the one the backend resolved. */
|
|
44
|
+
setRepoId(repoId: string): void;
|
|
45
|
+
complete(): void;
|
|
46
|
+
fail(error: unknown): void;
|
|
47
|
+
/** Ends the entry without history: nothing was downloaded (already cached, or joined another download). */
|
|
48
|
+
discard(): void;
|
|
49
|
+
};
|
|
50
|
+
export declare const downloadStatus: {
|
|
51
|
+
begin(download: {
|
|
52
|
+
type: GeneratorType;
|
|
53
|
+
repoId: string;
|
|
54
|
+
filename?: string | null;
|
|
55
|
+
}): DownloadHandle;
|
|
56
|
+
snapshot(): DownloadsSnapshot;
|
|
57
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This machine, as `/buttress/status` and the settings window describe it. Same shape as
|
|
3
|
+
* `HostInfo` in @fugood/buttress-ui, kept local so the emitted types do not need that package.
|
|
4
|
+
*/
|
|
5
|
+
export type HostFacts = {
|
|
6
|
+
cpuModel: string;
|
|
7
|
+
cpuCores: number;
|
|
8
|
+
totalMemoryBytes: number;
|
|
9
|
+
/** Unified memory: the GPU shares `totalMemoryBytes`. */
|
|
10
|
+
appleSilicon: boolean;
|
|
11
|
+
gpuName?: string;
|
|
12
|
+
};
|
|
13
|
+
export declare const readHostFacts: () => HostFacts;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fugood/buttress-server",
|
|
3
|
-
"version": "2.26.0-beta.
|
|
3
|
+
"version": "2.26.0-beta.20",
|
|
4
4
|
"main": "lib/index.mjs",
|
|
5
5
|
"types": "lib/index.d.ts",
|
|
6
6
|
"type": "module",
|
|
@@ -19,13 +19,13 @@
|
|
|
19
19
|
],
|
|
20
20
|
"scripts": {
|
|
21
21
|
"typecheck": "tsc --noEmit",
|
|
22
|
-
"build": "tsdown -c rolldown.config.js --config-loader native && tsc --noCheck --emitDeclarationOnly && cp ../buttress-backend-core/src/backends/mlx-bridge.py lib/mlx-bridge.py && cp ../../node_modules/quickjs-wasi/quickjs.wasm lib/quickjs.wasm",
|
|
23
|
-
"build:dist": "$npm_execpath scripts/build-distribution.js",
|
|
24
|
-
"release": "$npm_execpath scripts/build-distribution.js",
|
|
25
|
-
"release-beta": "$npm_execpath scripts/build-distribution.js --beta",
|
|
22
|
+
"build": "bun scripts/copy-status-page.js && tsdown -c rolldown.config.js --config-loader native && tsc --noCheck --emitDeclarationOnly && cp ../buttress-backend-core/src/backends/mlx-bridge.py lib/mlx-bridge.py && cp ../../node_modules/quickjs-wasi/quickjs.wasm lib/quickjs.wasm",
|
|
23
|
+
"build:dist": "$npm_execpath run --cwd ../buttress-ui build && $npm_execpath scripts/copy-status-page.js --require && $npm_execpath scripts/build-distribution.js",
|
|
24
|
+
"release": "$npm_execpath run --cwd ../buttress-ui build && $npm_execpath scripts/copy-status-page.js --require && $npm_execpath scripts/build-distribution.js",
|
|
25
|
+
"release-beta": "$npm_execpath run --cwd ../buttress-ui build && $npm_execpath scripts/copy-status-page.js --require && $npm_execpath scripts/build-distribution.js --beta",
|
|
26
26
|
"upload-release": "node scripts/upload-release.js",
|
|
27
27
|
"upload-beta": "node scripts/upload-release.js --beta",
|
|
28
|
-
"prepublish": "bun run build",
|
|
28
|
+
"prepublish": "bun run --cwd ../buttress-ui build && bun scripts/copy-status-page.js --require && bun run build",
|
|
29
29
|
"dev": "bun src/index.ts",
|
|
30
30
|
"start": "bun lib/index.mjs",
|
|
31
31
|
"start-with-node": "node lib/index.mjs"
|
|
@@ -70,10 +70,12 @@
|
|
|
70
70
|
},
|
|
71
71
|
"devDependencies": {
|
|
72
72
|
"@fugood/agent-tool-runtime": "^2.26.0-beta.19",
|
|
73
|
-
"@fugood/bricks-cli": "^2.26.0-beta.
|
|
73
|
+
"@fugood/bricks-cli": "^2.26.0-beta.20",
|
|
74
74
|
"@fugood/bricks-devtools-core": "^2.26.0-beta.18",
|
|
75
|
+
"@fugood/buttress-config": "^2.26.0-beta.20",
|
|
76
|
+
"@fugood/buttress-ui": "^2.26.0-beta.20",
|
|
75
77
|
"tsdown": "^0.22.4",
|
|
76
78
|
"typescript": "^7.0.2"
|
|
77
79
|
},
|
|
78
|
-
"gitHead": "
|
|
80
|
+
"gitHead": "ca31dd0b8e73e39b22addc5e34c33f5240ef64a1"
|
|
79
81
|
}
|