@prismshadow/penguin-server 0.0.1 → 0.1.1

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 CHANGED
@@ -37,7 +37,7 @@ pnpm --filter @prismshadow/penguin-server start # node dist/index.js
37
37
 
38
38
  - **CSRF**: session cookie is `SameSite=Lax` and writes accept only `Content-Type: application/json`; no CSRF token yet.
39
39
  - **No login rate limiting**: add throttling at a reverse proxy for public deployments.
40
- - **Built-in admin starts as `admin` / `admin123`**: change it immediately (a banner keeps reminding until you do).
40
+ - **Built-in admin starts as `admin` / `penguin-2026`**: change it immediately (a banner keeps reminding until you do).
41
41
  - Passwords use `node:crypto` scrypt (`scrypt$N$r$p$salt$hash`, timingSafeEqual); login sessions renew on a 7-day sliding window; the DB stores only the token's sha256.
42
42
  - Model credentials live in the Project's hidden 0600 config file; the API always masks them.
43
43
  - Behind a reverse proxy, disable response buffering for SSE paths (the server already sends `X-Accel-Buffering: no`) and forward `x-forwarded-proto` to enable Secure cookies.
@@ -159,6 +159,13 @@ interface ModelInfo {
159
159
  * unset (= treated as supported).
160
160
  */
161
161
  vision?: boolean;
162
+ /**
163
+ * Per-model max output tokens (TOML `max_tokens` annotation; user-only, never preset by the
164
+ * built-in catalog): when set it wins over the Agent's `system_config.model.max_tokens`;
165
+ * unset = inherit the Agent value. Lets a small-context model cap its output below the
166
+ * seeded per-Agent default (32000), which cannot fit into e.g. a 32k context window.
167
+ */
168
+ maxTokens?: number;
162
169
  pricing?: ModelPricingDto;
163
170
  /** Environment variable name to fall back to when api_key is empty (e.g. ANTHROPIC_API_KEY); unset if no known fallback. */
164
171
  envKey?: string;
@@ -192,6 +199,8 @@ interface ModelUpdateEntry {
192
199
  clientType?: string;
193
200
  /** Whether image input (vision/multimodal) is supported; omitted = supported (not persisted). */
194
201
  vision?: boolean;
202
+ /** Per-model max output tokens, a positive integer (wins over the Agent config); omitted = inherit the Agent value (the annotation is cleared). */
203
+ maxTokens?: number;
195
204
  pricing?: ModelPricingDto;
196
205
  /** Providing it overwrites and updates createdAt; omitting it keeps the existing value. */
197
206
  apiKey?: string;
@@ -222,6 +231,8 @@ interface ModelTestRequest {
222
231
  apiKey?: string;
223
232
  /** "Clear saved API key" is checked: the test does **not** fall back to the stored key (tests against the current draft). */
224
233
  clearApiKey?: boolean;
234
+ /** Speed-test mode: raises the probe's output cap (16 -> 64 tokens) so TTFT/TPS are measurable; costs a little more quota. */
235
+ speed?: boolean;
225
236
  /**
226
237
  * base URL (not secret; the frontend always sends the form's current value): a string
227
238
  * means use it, `null` means explicitly clear it (no fallback to the stored value),
@@ -231,10 +242,23 @@ interface ModelTestRequest {
231
242
  /** AgentHub client protocol; required for unsaved custom models (otherwise the id can't be auto-routed). */
232
243
  clientType?: string;
233
244
  }
234
- /** Connectivity test result: carries round-trip latency when ok, and a reason on failure (truncated raw provider error). */
245
+ /**
246
+ * Connectivity test result: carries round-trip latency when ok, and a reason on failure
247
+ * (truncated raw provider error). When streamed content was observed, also carries the
248
+ * time-to-first-token and, when usage was reported (completed streams), the output rate.
249
+ */
235
250
  interface ModelTestResponse {
236
251
  ok: boolean;
237
252
  latencyMs?: number;
253
+ /** Time from request start to the first streamed content (thinking or text), ms. */
254
+ ttftMs?: number;
255
+ /**
256
+ * Output tokens per second over the streaming window (first content -> stream end), 1dp.
257
+ * Omitted unless the sample is large enough to mean anything: a reply of a few tokens is
258
+ * dominated by the final chunk's round trip, so the rate it yields tracks network jitter
259
+ * rather than the model. Callers render TTFT alone in that case.
260
+ */
261
+ tps?: number;
238
262
  message?: string;
239
263
  }
240
264
  /** Read-only vault entry display: key name + masked value; plaintext is never sent. */
@@ -277,6 +301,8 @@ interface AgentSummary {
277
301
  vaultKeyCount: number;
278
302
  /** Schedule count (number of .toml files under agent_state/schedule/, including invalid ones). */
279
303
  scheduleCount: number;
304
+ /** Installed Skill count (number of agent_state/skills/<name>/ directories with a SKILL.md). */
305
+ skillCount: number;
280
306
  }
281
307
  interface AgentsResponse {
282
308
  agents: AgentSummary[];
@@ -350,7 +376,7 @@ interface SessionInfo {
350
376
  approvalMode: ApprovalMode;
351
377
  /** Short title auto-generated by the model after the first turn; unset until generated (frontend shows "New Chat"). */
352
378
  title?: string;
353
- /** Session source (for list badges); unset for user-created sessions. */
379
+ /** Session source (for list badges/folders), derived from core session_meta — the single source of truth (not stored in the DB); unset for user-created sessions. */
354
380
  source?: SessionSource;
355
381
  createdAt: string;
356
382
  status: SessionStatus;
@@ -379,12 +405,12 @@ interface DirListResponse {
379
405
  entries: DirEntryInfo[];
380
406
  }
381
407
  interface SessionCreateRequest {
382
- /** Upstream id of the session's model (paired with provider); defaults to the Project's default Model. */
408
+ /** Upstream id of the session's model; always sent together with provider. Omit both for the Project's default Model. */
383
409
  modelId?: string;
384
410
  /**
385
- * Provider group for `modelId`; when omitted, resolved via resolveModelRef semantics —
386
- * modelId can only be resolved if it's globally unique by exact match in the config;
387
- * 0 or multiple matches return 400.
411
+ * Provider group for `modelId`. A model reference is always a complete
412
+ * (provider, modelId) pair — the provider is never inferred, so sending one field
413
+ * without the other returns 400 instead of being resolved.
388
414
  */
389
415
  provider?: string;
390
416
  /** Any existing directory on the server; defaults to auto-creating a temporary Workspace. */
@@ -822,9 +848,9 @@ interface ScheduleItem {
822
848
  /** Bound target Session; defaults to creating a new Session each time. */
823
849
  sessionId?: string;
824
850
  workspace?: string;
825
- /** Model for new-Session mode (upstream id, paired with provider); defaults to the Project's default reference. */
851
+ /** Model for new-Session mode (upstream id, always paired with provider); absent means the Project's default reference. */
826
852
  modelId?: string;
827
- /** Provider group for `modelId`; when omitted, resolved via resolveModelRef semantics (resolvable only on a unique match). */
853
+ /** Provider group for `modelId`; present exactly when `modelId` is — a model reference is always a pair. */
828
854
  provider?: string;
829
855
  status: ScheduleStatus;
830
856
  invalidReason?: string;
@@ -852,9 +878,12 @@ interface ScheduleUpsertRequest {
852
878
  endAt?: string;
853
879
  sessionId?: string;
854
880
  workspace?: string;
855
- /** Model for new-Session mode (upstream id); defaults to the Project's default reference. */
881
+ /** Model for new-Session mode (upstream id); always sent together with provider, omit both for the Project's default reference. */
856
882
  modelId?: string;
857
- /** Provider group for `modelId`; when omitted, validated as uniquely resolvable via resolveModelRef semantics at save/reconciliation time. */
883
+ /**
884
+ * Provider group for `modelId`. Both fields are sent as a pair (400 otherwise); the
885
+ * pair is checked against the Project config at save/reconciliation time.
886
+ */
858
887
  provider?: string;
859
888
  }
860
889
  interface AgentImportRequest {