@wxip/dsh-sub2api 0.2.2

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.
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Global image-generation tool.
3
+ *
4
+ * These call a configured Sub2API model independently of the current chat
5
+ * route, so a text-only session can still create images. Results include a workspace path and an image attachment.
6
+ *
7
+ * @module dsh-sub2api/image-tools
8
+ */
9
+ import type { Context } from '@deepseek-ai/cordis';
10
+ import { type Config, type ProviderProfile } from './index.js';
11
+ export declare const GENERATE_IMAGE_NAME = "generate_image";
12
+ export declare const DEFAULT_IMAGE_TOOL_TIMEOUT_MS = 180000;
13
+ export declare const DEFAULT_MAX_IMAGE_BYTES: number;
14
+ export interface ImageToolHost {
15
+ config: () => Config;
16
+ resolveApiKey: (route: string, profile: ProviderProfile) => Promise<string>;
17
+ }
18
+ export declare function registerImageTools(ctx: Context, host: ImageToolHost): void;
package/lib/index.d.ts ADDED
@@ -0,0 +1,148 @@
1
+ /**
2
+ * Sub2API gateway integration for the harness LLM seam.
3
+ *
4
+ * One OpenAI-compatible base URL, many provider routes. In the sub2api
5
+ * gateway each API key is bound to a group, and the group decides the
6
+ * platform (openai / anthropic / grok) and the model list the key
7
+ * can serve.
8
+ *
9
+ * The LLM routes this plugin used to own (`sub2api-openai` / `sub2api-claude`
10
+ * / `sub2api-grok`) are served by the harness's own pi-ai
11
+ * adapter (`dsh-llm-pi-ai`, mounted dormant by dsh-base): protocol
12
+ * serialization, streaming, usage mapping, replay, and retry handling all live
13
+ * in pi-ai, which speaks each platform's native wire protocol upstream (OpenAI
14
+ * → Responses API, Claude → Messages API, the rest → chat/completions).
15
+ * This plugin contributes the sub2api-specific surface on top: the
16
+ * `llm-sub2api:` settings section and its web page (baseURL + per-key model
17
+ * catalogs + keys), gateway model discovery and usage probes, the global
18
+ * image-generation tools, and a bridge
19
+ * that materializes the configured groups as `llm-pi-ai:` provider profiles
20
+ * the moment the section lands (see `./pi-ai.ts`).
21
+ *
22
+ * Keys are stored through the harness credential seam; the base URL and
23
+ * per-key model catalogs live in the `llm-sub2api:` settings section
24
+ * (the active profile `cordis.patch.yml`, written by the web settings page).
25
+ *
26
+ * @module dsh-sub2api
27
+ */
28
+ import type { Context, Volatile } from '@deepseek-ai/cordis';
29
+ import z from '@deepseek-ai/schemastery';
30
+ export { PI_AI_NS, ROUTE_PREFIX, syncPiAiProfiles, translateToPiAi, type PiAiModelProfile, type PiAiProviderProfile, type PiAiSettingsSection, } from './pi-a./pi-ai.jsort { applyPiAiMultiTurnPatch, type PiAiPatchResult } from './pi-a./pi-ai-patch.jsort declare const name = "llm-sub2api";
31
+ export declare const inject: string[];
32
+ /** Context capacity assumed for a model neither configuration nor discovery sizes. */
33
+ export declare const DEFAULT_CONTEXT_WINDOW = 128000;
34
+ /** Output capability assumed for a model neither configuration nor discovery sizes. */
35
+ export declare const DEFAULT_MAX_TOKENS = 8192;
36
+ /**
37
+ * Reasoning effort levels exposed for reasoning-capable models. The gateway
38
+ * speaks the OpenAI chat-completions protocol, so the ids are the OpenAI
39
+ * `reasoning_effort` vocabulary and are sent through verbatim. Per-model
40
+ * configuration (filled from models.dev `reasoning_options`) may expose
41
+ * additional vocabulary such as `none`, `xhigh`, or `max`.
42
+ */
43
+ export declare const REASONING_EFFORTS: readonly {
44
+ id: string;
45
+ name: string;
46
+ }[];
47
+ export type ProviderKey = 'openai' | 'claude' | 'grok';
48
+ export interface ProviderDef {
49
+ key: ProviderKey;
50
+ route: string;
51
+ label: string;
52
+ icon: string;
53
+ }
54
+ /** The provider routes this plugin owns, keyed by sub2api platform name. */
55
+ export declare const PROVIDERS: readonly ProviderDef[];
56
+ export interface CatalogModel {
57
+ /** Model id sent to the provider and accepted by {@link GenerateOptions.model}. */
58
+ id: string;
59
+ /** Display name for selectors; defaults to the id. */
60
+ name?: string;
61
+ /** Maximum combined request and response context in tokens. */
62
+ contextWindow?: number;
63
+ /** Maximum output tokens. */
64
+ maxTokens?: number;
65
+ /**
66
+ * Accepted request modalities. Absent or empty: the adapter guesses from
67
+ * the model id (multimodal families such as gpt/claude/gemini/grok/glm
68
+ * declare `[text, image]`, everything else stays `[text]`). Non-empty:
69
+ * exactly those modalities, e.g. `[text]` to pin a multimodal-looking
70
+ * model to text only.
71
+ */
72
+ input?: Array<'text' | 'image'>;
73
+ /**
74
+ * Reasoning effort levels selectable for this model. Absent: every non-image
75
+ * model on any route exposes low/medium/high (the gateway is OpenAI-compatible
76
+ * on all routes). Empty array: reasoning effort is explicitly off for this
77
+ * model. Non-empty: exposes exactly those levels verbatim (e.g. models.dev
78
+ * vocabularies such as `xhigh`/`max`/`none`).
79
+ */
80
+ reasoningEfforts?: string[];
81
+ }
82
+ export interface ProviderProfile {
83
+ /** Credential reference (environment-variable name) resolved per request through `ctx.credentials`. */
84
+ apiKeyEnv?: string;
85
+ /**
86
+ * Wire protocol spoken to the gateway for this platform group. Absent
87
+ * selects the group's native protocol (openai → responses, claude →
88
+ * messages, grok → chat/completions). Explicitly name a protocol to
89
+ * force a different endpoint, e.g. a gateway that serves a group through
90
+ * chat/completions after all.
91
+ */
92
+ api?: ApiProtocol;
93
+ /** Advisory model catalog for this route. */
94
+ models?: CatalogModel[];
95
+ }
96
+ /** One dedicated model used by a global image tool, independent of the chat route. */
97
+ export interface ImageToolModelRef {
98
+ /** Sub2API platform that owns the key and catalog (`openai` / `claude` / `grok`). */
99
+ provider: string;
100
+ /** Model id sent to the gateway. */
101
+ model: string;
102
+ }
103
+ export interface ImageToolsConfig {
104
+ /** Image-generation model used by the global `generate_image` tool. */
105
+ generate?: ImageToolModelRef;
106
+ }
107
+ export interface Config {
108
+ /** OpenAI-compatible gateway base URL, e.g. http://localhost:8080/v1. */
109
+ baseURL: string;
110
+ /** Per-platform provider profiles keyed by sub2api platform name. */
111
+ providers: Record<ProviderKey, ProviderProfile>;
112
+ /** Dedicated models for the global image-generation tools. */
113
+ tools?: ImageToolsConfig;
114
+ }
115
+ /** Live configuration references owned by the DSH Loader. */
116
+ export interface LiveConfig {
117
+ baseURL: Volatile<string>;
118
+ providers: Volatile<Record<ProviderKey, ProviderProfile>>;
119
+ tools: Volatile<ImageToolsConfig>;
120
+ }
121
+ /** Capture one configuration snapshot for a gateway operation. */
122
+ export declare function readConfig(config: LiveConfig): Config;
123
+ export declare const Config: z<Partial<Config>, LiveConfig>;
124
+ /**
125
+ * Wire protocol the adapter speaks to the gateway for one route. Each value
126
+ * names a real endpoint: `openai-completions` → `/chat/completions`,
127
+ * `openai-responses` → `/responses`, `anthropic-messages` → `/messages`.
128
+ */
129
+ export type ApiProtocol = 'openai-completions' | 'openai-responses' | 'anthropic-messages';
130
+ export declare const API_PROTOCOLS: readonly ApiProtocol[];
131
+ /** Resolve the wire protocol for one provider key; shared by chat routes and the global image tools. */
132
+ export declare function apiProtocolForKey(key: ProviderKey, profile: ProviderProfile): ApiProtocol;
133
+ /**
134
+ * The OpenAI-style API root for a gateway base URL. The Sub2API settings page
135
+ * stores the bare host (e.g. `https://gateway.example:6443`); OpenAI-compatible
136
+ * endpoints (`/responses`, `/chat/completions`, `/models`, `/usage`) live under
137
+ * the `/v1` root, so it is appended here when missing. A URL already carrying
138
+ * `/v1` passes through unchanged.
139
+ */
140
+ export declare function gatewayApiRoot(baseURL: string): string;
141
+ /**
142
+ * The bare-host form the Anthropic SDK expects: `@anthropic-ai/sdk` treats the
143
+ * configured URL as the host and always appends `/v1/messages` itself, so a
144
+ * `/v1`-rooted URL would hit `/v1/v1/messages` (404). Strips a trailing `/v1`
145
+ * when present.
146
+ */
147
+ export declare function gatewayAnthropicRoot(baseURL: string): string;
148
+ export declare function apply(ctx: Context, config: LiveConfig): void;