@hadooppei/hwcode 0.2.0 → 0.2.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/.env.example +2 -7
- package/.pi/lib/models/provider-config.ts +3 -3
- package/.pi/model-providers.json +2 -50
- package/README.md +30 -40
- package/bin/hwcode.js +1 -1
- package/package.json +2 -2
package/.env.example
CHANGED
|
@@ -1,10 +1,5 @@
|
|
|
1
|
-
# Keep real credentials outside version control.
|
|
2
|
-
#
|
|
3
|
-
# .pi/model-providers.json.
|
|
4
|
-
PI_LOCAL_MODEL_API_KEY=local
|
|
5
|
-
|
|
6
|
-
# Optional credential used as the default when logging in to the configurable
|
|
7
|
-
# "hw" provider. Leave unset for a keyless local endpoint.
|
|
1
|
+
# Keep real credentials outside version control. Set this value to provide the
|
|
2
|
+
# required "hw" credential through the environment, or enter it through /login.
|
|
8
3
|
# HW_API_KEY=
|
|
9
4
|
|
|
10
5
|
# OPENAI_API_KEY=
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { dirname, join } from "node:path";
|
|
2
2
|
import { fileURLToPath } from "node:url";
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import { readJsonObject } from "../runtime/config.ts";
|
|
5
5
|
|
|
6
6
|
export type ModelInput = "text" | "image";
|
|
7
7
|
export interface ConfiguredModel { id: string; name?: string; reasoning?: boolean; input?: ModelInput[]; contextWindow?: number; maxTokens?: number; }
|
|
@@ -42,9 +42,9 @@ function validateModel(providerId: string, model: ConfiguredModel): void {
|
|
|
42
42
|
if (model.maxTokens !== undefined && !isPositiveNumber(model.maxTokens)) throw new Error(`Model "${model.id}" has an invalid maxTokens`);
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
export function loadModelProvidersConfig(
|
|
45
|
+
export function loadModelProvidersConfig(): ModelProvidersConfig {
|
|
46
46
|
const source = "model-providers.json";
|
|
47
|
-
const config =
|
|
47
|
+
const config = readJsonObject(BUNDLED_CONFIG_PATH) as ModelProvidersConfig & Record<string, unknown>;
|
|
48
48
|
if (!Array.isArray(config.providers) || config.providers.length === 0) throw new Error(`${source} must contain a non-empty providers array`);
|
|
49
49
|
const providerIds = new Set<string>();
|
|
50
50
|
for (const provider of config.providers) {
|
package/.pi/model-providers.json
CHANGED
|
@@ -1,53 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"providers": [
|
|
3
|
-
{
|
|
4
|
-
"id": "local",
|
|
5
|
-
"name": "Qwen3 VL (8081)",
|
|
6
|
-
"baseUrl": "http://127.0.0.1:8081",
|
|
7
|
-
"apiKeyEnv": "PI_LOCAL_MODEL_API_KEY",
|
|
8
|
-
"modelDefaults": {
|
|
9
|
-
"contextWindow": 1000000,
|
|
10
|
-
"maxTokens": 8192
|
|
11
|
-
},
|
|
12
|
-
"models": [
|
|
13
|
-
{
|
|
14
|
-
"id": "qwen3-VL:2b",
|
|
15
|
-
"name": "Qwen3 VL 2B",
|
|
16
|
-
"input": ["text", "image"],
|
|
17
|
-
"contextWindow": 1000000,
|
|
18
|
-
"maxTokens": 8192
|
|
19
|
-
}
|
|
20
|
-
]
|
|
21
|
-
},
|
|
22
|
-
{
|
|
23
|
-
"id": "local-8080",
|
|
24
|
-
"name": "Qwen3.5 9B (8080)",
|
|
25
|
-
"baseUrl": "http://127.0.0.1:8080",
|
|
26
|
-
"apiKeyEnv": "PI_LOCAL_MODEL_API_KEY",
|
|
27
|
-
"modelDefaults": {
|
|
28
|
-
"contextWindow": 1000000,
|
|
29
|
-
"maxTokens": 8192
|
|
30
|
-
},
|
|
31
|
-
"models": [
|
|
32
|
-
{
|
|
33
|
-
"id": "Qwen3.5-9B-Q4_K_M",
|
|
34
|
-
"name": "Qwen3.5 9B Q4_K_M",
|
|
35
|
-
"input": ["text"],
|
|
36
|
-
"contextWindow": 1000000,
|
|
37
|
-
"maxTokens": 8192
|
|
38
|
-
}
|
|
39
|
-
]
|
|
40
|
-
},
|
|
41
3
|
{
|
|
42
4
|
"id": "hw",
|
|
43
5
|
"name": "Huawei MaaS",
|
|
44
|
-
"baseUrl": "http://127.0.0.1:8080/v1",
|
|
45
6
|
"apiKeyEnv": "HW_API_KEY",
|
|
46
7
|
"login": {
|
|
47
8
|
"enabled": true,
|
|
48
9
|
"promptBaseUrl": true,
|
|
49
10
|
"promptApiKey": true,
|
|
50
|
-
"apiKeyRequired":
|
|
11
|
+
"apiKeyRequired": true,
|
|
51
12
|
"catalogPath": "models",
|
|
52
13
|
"timeoutMs": 15000
|
|
53
14
|
},
|
|
@@ -55,16 +16,7 @@
|
|
|
55
16
|
"input": ["text"],
|
|
56
17
|
"contextWindow": 1000000,
|
|
57
18
|
"maxTokens": 8192
|
|
58
|
-
}
|
|
59
|
-
"models": [
|
|
60
|
-
{
|
|
61
|
-
"id": "Qwen3.5-9B-Q4_K_M",
|
|
62
|
-
"name": "Qwen3.5 9B Q4_K_M",
|
|
63
|
-
"input": ["text"],
|
|
64
|
-
"contextWindow": 1000000,
|
|
65
|
-
"maxTokens": 8192
|
|
66
|
-
}
|
|
67
|
-
]
|
|
19
|
+
}
|
|
68
20
|
}
|
|
69
21
|
]
|
|
70
22
|
}
|
package/README.md
CHANGED
|
@@ -21,10 +21,11 @@ hwcode
|
|
|
21
21
|
Run `hwcode --help` for the HWCode command reference, including model,
|
|
22
22
|
session, tool, and workflow options.
|
|
23
23
|
|
|
24
|
-
`npx @hadooppei/hwcode` is also supported without a global installation. HWCode
|
|
25
|
-
project's `.env` file when present and keeps Pi's normal user-level auth
|
|
26
|
-
session storage. Project-local
|
|
27
|
-
built-in HWCode profile
|
|
24
|
+
`npx @hadooppei/hwcode` is also supported without a global installation. HWCode
|
|
25
|
+
loads a project's `.env` file when present and keeps Pi's normal user-level auth
|
|
26
|
+
and session storage. Project-local Pi resources continue to load alongside the
|
|
27
|
+
built-in HWCode profile, except for HWCode's package-scoped model-provider
|
|
28
|
+
definition described below.
|
|
28
29
|
|
|
29
30
|
## Repository setup
|
|
30
31
|
|
|
@@ -38,45 +39,31 @@ On first launch, review and accept Pi's project-trust prompt so it can load the
|
|
|
38
39
|
|
|
39
40
|
## Model providers
|
|
40
41
|
|
|
41
|
-
|
|
42
|
-
|
|
42
|
+
The published `.pi/model-providers.json` is package-scoped and is not replaced
|
|
43
|
+
by a file in the current project. It registers the configurable `hw` provider
|
|
44
|
+
without shipping a machine-specific endpoint or a pre-populated model catalog.
|
|
45
|
+
Use Pi's native `/login` flow, select `Huawei MaaS`, and enter the endpoint and
|
|
46
|
+
API key. The key can instead come from `HW_API_KEY`. HWCode then discovers every model exposed by the
|
|
47
|
+
OpenAI-compatible endpoint and Pi stores the selected endpoint, credential, and
|
|
48
|
+
dynamic catalog in its user-level stores.
|
|
43
49
|
|
|
44
|
-
|
|
45
|
-
{
|
|
46
|
-
"id": "local-example",
|
|
47
|
-
"name": "Local example",
|
|
48
|
-
"baseUrl": "http://127.0.0.1:8082",
|
|
49
|
-
"apiKeyEnv": "PI_LOCAL_MODEL_API_KEY",
|
|
50
|
-
"models": [
|
|
51
|
-
{
|
|
52
|
-
"id": "model-id",
|
|
53
|
-
"input": ["text", "image"],
|
|
54
|
-
"contextWindow": 32768,
|
|
55
|
-
"maxTokens": 8192
|
|
56
|
-
}
|
|
57
|
-
]
|
|
58
|
-
}
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
Login providers use Pi's native `/login` flow and discover every model exposed
|
|
62
|
-
by an OpenAI-compatible model endpoint:
|
|
50
|
+
The published provider is equivalent to:
|
|
63
51
|
|
|
64
52
|
```json
|
|
65
53
|
{
|
|
66
54
|
"id": "hw",
|
|
67
|
-
"name": "
|
|
68
|
-
"baseUrl": "http://127.0.0.1:8080/v1",
|
|
55
|
+
"name": "Huawei MaaS",
|
|
69
56
|
"apiKeyEnv": "HW_API_KEY",
|
|
70
57
|
"login": {
|
|
71
58
|
"enabled": true,
|
|
72
59
|
"promptBaseUrl": true,
|
|
73
60
|
"promptApiKey": true,
|
|
74
|
-
"apiKeyRequired":
|
|
61
|
+
"apiKeyRequired": true,
|
|
75
62
|
"catalogPath": "models"
|
|
76
63
|
},
|
|
77
64
|
"modelDefaults": {
|
|
78
65
|
"input": ["text"],
|
|
79
|
-
"contextWindow":
|
|
66
|
+
"contextWindow": 1000000,
|
|
80
67
|
"maxTokens": 8192
|
|
81
68
|
}
|
|
82
69
|
}
|
|
@@ -84,12 +71,14 @@ by an OpenAI-compatible model endpoint:
|
|
|
84
71
|
|
|
85
72
|
`id` is the stable credential and cache key; `name` is the configurable label
|
|
86
73
|
shown alongside other providers in `/login`. A login authenticates the whole
|
|
87
|
-
provider and publishes its complete model catalog to `/model`.
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
74
|
+
provider and publishes its complete model catalog to `/model`. Unknown models
|
|
75
|
+
default to text-only. Keep real API keys in `.env` or enter them through
|
|
76
|
+
`/login`; Pi stores entered credentials in its own auth store rather than the
|
|
77
|
+
package configuration.
|
|
78
|
+
|
|
79
|
+
Repository maintainers can refer to `.pi/model-providers.json.template` for the
|
|
80
|
+
previous local static-provider examples, including multimodal metadata. The
|
|
81
|
+
template is not loaded at runtime and is explicitly excluded from npm packages.
|
|
93
82
|
|
|
94
83
|
## Welcome screen
|
|
95
84
|
|
|
@@ -174,9 +163,9 @@ commands, tools, and UI. Reusable behavior lives under `.pi/lib/`:
|
|
|
174
163
|
- `context/` and `models/` own compaction and provider-configuration policy.
|
|
175
164
|
|
|
176
165
|
`settings.json` is layered as defaults → profile → project for settings such as
|
|
177
|
-
context and hidden commands. `welcome.json`
|
|
178
|
-
|
|
179
|
-
|
|
166
|
+
context and hidden commands. `welcome.json` uses a single replacing resource.
|
|
167
|
+
`model-providers.json` is deliberately package-scoped so a project cannot
|
|
168
|
+
silently replace login providers or reintroduce machine-local defaults.
|
|
180
169
|
|
|
181
170
|
## Working directory
|
|
182
171
|
|
|
@@ -204,8 +193,9 @@ HWCode defaults locally configured and dynamically discovered models to a
|
|
|
204
193
|
1,000,000-token context window and caps configured or provider-reported values
|
|
205
194
|
at that limit. If an OpenAI-compatible model catalog reports a smaller
|
|
206
195
|
`context_window`, `context_length`, `max_context_length`, `max_model_len`, or
|
|
207
|
-
`n_ctx`, the smaller server value wins.
|
|
208
|
-
|
|
196
|
+
`n_ctx`, the smaller server value wins. The package-scoped provider's
|
|
197
|
+
`modelDefaults.contextWindow` can also select a smaller limit for dynamically
|
|
198
|
+
discovered models.
|
|
209
199
|
|
|
210
200
|
The default context policy is configured under `hwcode.context` in
|
|
211
201
|
`.pi/settings.json`:
|
package/bin/hwcode.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hadooppei/hwcode",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "A customizable terminal coding agent with local-model support and HWCode workflows.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"pi": "node --env-file-if-exists=.env ./bin/hwcode.js",
|
|
27
27
|
"test": "node --test .pi/lib/*.test.ts",
|
|
28
28
|
"test:workflows": "npm test",
|
|
29
|
-
"prepack": "npm test"
|
|
29
|
+
"prepack": "npm test && node scripts/audit-package.mjs"
|
|
30
30
|
},
|
|
31
31
|
"engines": {
|
|
32
32
|
"node": ">=22.19.0"
|