@mokuyoaxis/dsh-iris 0.3.0-alpha.1 → 0.3.0-beta.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/CHANGELOG.md +63 -1
- package/README.en.md +20 -13
- package/README.md +20 -13
- package/bin/dsh-iris.js +143 -51
- package/docs/AGENT_CORE_QUICKSTART.md +2 -2
- package/docs/AGENT_QUICKSTART.md +1 -1
- package/docs/ARCHITECTURE.md +5 -5
- package/docs/ARTIFACT_MANIFEST.md +4 -0
- package/docs/AUDIO_FLOWS.md +20 -4
- package/docs/BETA_SCOPE.md +42 -0
- package/docs/CONTACT_SHEET.md +1 -1
- package/docs/CORE_CONNECTIONS.md +3 -1
- package/docs/CORE_QUICKSTART.md +7 -5
- package/docs/CORE_RUNTIME_CONTRACT.md +3 -3
- package/docs/CORE_SERVICE.md +9 -5
- package/docs/CORE_SKILLS.md +2 -2
- package/docs/DSH_COMPATIBILITY.md +11 -1
- package/docs/DSH_CORE_MIGRATION.md +6 -0
- package/docs/DSH_RUNTIME.md +2 -2
- package/docs/HEADLESS_CLI.md +29 -4
- package/docs/HOST_ADAPTER_CONTRACT.md +5 -3
- package/docs/IMAGE_FLOW.md +2 -2
- package/docs/IMAGE_GENERATION.md +1 -1
- package/docs/LOCAL_API.md +2 -2
- package/docs/LOCAL_API_CONTRACT.md +17 -15
- package/docs/LOCAL_CREATION.md +2 -2
- package/docs/LOCAL_OPERATIONS.md +2 -2
- package/docs/LOCAL_SELECTION.md +1 -1
- package/docs/LOCAL_WEB.md +11 -5
- package/docs/MCP.md +30 -9
- package/docs/MEDIA_SCHEDULING.md +72 -0
- package/docs/NETWORK_RESOURCES.md +106 -0
- package/docs/NETWORK_ROUTING.md +103 -0
- package/docs/NETWORK_WORKBENCH.md +65 -0
- package/docs/PANEL_EXTENSIONS.md +1 -1
- package/docs/PLUGINS.md +9 -5
- package/docs/PLUGIN_DEVELOPMENT.md +39 -0
- package/docs/PLUGIN_STARTUP.md +15 -2
- package/docs/PROVIDER_ADAPTER_CONTRACT.md +8 -2
- package/docs/PROVIDER_CREDENTIALS.md +67 -0
- package/docs/PROVIDER_EXTENSIONS.md +8 -4
- package/docs/PROVIDER_HEALTH.md +4 -2
- package/docs/PROVIDER_NETWORK.md +45 -0
- package/docs/PROVIDER_PLUGIN_CONTRACT.md +24 -0
- package/docs/PROVIDER_SETTINGS.md +13 -7
- package/docs/PROVIDER_SUBMISSION_CONTRACT.md +3 -1
- package/docs/ROADMAP.md +6 -6
- package/docs/SECURITY.md +1 -1
- package/docs/SYNC_DELIVERY_RECOVERY.md +5 -1
- package/docs/VIDEO_FLOWS.md +89 -0
- package/docs/VISION_MODEL.md +2 -0
- package/docs/WEB_PROTOTYPE.md +3 -3
- package/docs/WEB_RECOVERY.md +2 -2
- package/docs/WORKBENCH_ARTIFACTS.md +6 -0
- package/docs/WORKBENCH_LOGIN.md +2 -2
- package/docs/releases/0.3.0-beta.1.md +34 -0
- package/docs/screenshots.md +2 -2
- package/lib/actions.js +5 -4
- package/lib/adapters.js +58 -41
- package/lib/api.js +23 -13
- package/lib/application-runtime.js +44 -15
- package/lib/application-writer.js +193 -0
- package/lib/client.d.ts +3 -3
- package/lib/client.js +62 -25
- package/lib/comfyui-adapter.js +3 -2
- package/lib/comfyui-client.js +10 -1
- package/lib/command-service.js +18 -5
- package/lib/config.js +13 -9
- package/lib/configured-image-runtime.js +28 -9
- package/lib/connection-skill.js +9 -0
- package/lib/core-artifact-store.js +68 -26
- package/lib/core-bridge-tools.js +5 -3
- package/lib/core-capability-catalog.js +21 -11
- package/lib/core-delivery-cache.js +8 -3
- package/lib/core-service-client.js +6 -2
- package/lib/core-tasks.js +86 -11
- package/lib/creation-request-store.js +8 -5
- package/lib/doctor.js +2 -2
- package/lib/dsh-core-adapter.js +61 -9
- package/lib/dsh-provider-config.js +1 -1
- package/lib/dsh-service-bridge.js +1 -0
- package/lib/flow-store.js +64 -17
- package/lib/image-flow.js +39 -17
- package/lib/index.js +10 -5
- package/lib/local-api-projection.js +6 -2
- package/lib/local-api.js +137 -49
- package/lib/local-creation.js +12 -5
- package/lib/local-operations.js +2 -2
- package/lib/local-request-root.js +2 -2
- package/lib/local-web-assets.js +2 -0
- package/lib/mcp-http.js +82 -9
- package/lib/mcp-server.js +23 -1
- package/lib/media-scheduler.js +194 -0
- package/lib/model-directory-service.js +25 -8
- package/lib/music-transport.js +4 -2
- package/lib/network-config-service.js +123 -0
- package/lib/network-config.js +127 -0
- package/lib/network-doctor.js +94 -0
- package/lib/network-management.js +51 -0
- package/lib/network-policy.js +19 -0
- package/lib/network-route-evidence.js +38 -0
- package/lib/network-routing.js +283 -0
- package/lib/operation-runner.js +83 -38
- package/lib/operation-store.js +6 -6
- package/lib/plugins.d.ts +25 -6
- package/lib/plugins.js +2 -1
- package/lib/provider-adapter.js +2 -2
- package/lib/provider-adapters.js +37 -5
- package/lib/provider-catalog.js +33 -16
- package/lib/provider-config-format.js +51 -0
- package/lib/provider-config-service.js +52 -22
- package/lib/provider-context.d.ts +90 -0
- package/lib/provider-context.js +42 -0
- package/lib/provider-credentials.js +97 -0
- package/lib/provider-diagnostics.js +5 -5
- package/lib/provider-health.js +10 -5
- package/lib/provider-monitor.js +5 -3
- package/lib/provider-network.js +52 -0
- package/lib/provider-protocol.js +3 -2
- package/lib/provider-registry.js +15 -5
- package/lib/provider-response.js +10 -0
- package/lib/provider-settings.js +14 -12
- package/lib/provider-task-runner.js +113 -37
- package/lib/provider-transport.js +16 -0
- package/lib/render.js +11 -1
- package/lib/scheduling-policy.js +66 -0
- package/lib/tasks.js +3 -2
- package/lib/video-flow-input.js +16 -0
- package/lib/video-input.js +12 -5
- package/lib/vision-model-routing.js +2 -0
- package/lib/web/app.js +107 -46
- package/lib/web/connections.js +151 -12
- package/lib/web/creation.js +29 -25
- package/lib/web/flow-view.js +4 -3
- package/lib/web/gallery.js +17 -16
- package/lib/web/index.html +58 -5
- package/lib/web/media-client.js +18 -4
- package/lib/web/network.js +232 -0
- package/lib/web/plugin-panel.js +4 -2
- package/lib/web/plugin-status.js +140 -0
- package/lib/web/providers.js +34 -13
- package/lib/web/recovery.js +2 -2
- package/lib/web/styles.css +54 -1
- package/lib/web/transport.js +6 -1
- package/lib/workbench-artifacts.js +3 -2
- package/package.json +5 -2
- package/skills/iris-core/references/comfyui.md +1 -1
- package/templates/plugin-starter/LICENSE +21 -0
- package/templates/plugin-starter/README.md +74 -0
- package/templates/plugin-starter/assets/peach.png +0 -0
- package/templates/plugin-starter/assets/violet.png +0 -0
- package/templates/plugin-starter/index.mjs +27 -0
- package/templates/plugin-starter/package.json +18 -0
- package/templates/plugin-starter/scripts/core-cli.mjs +20 -0
- package/templates/plugin-starter/scripts/environment.mjs +65 -0
- package/templates/plugin-starter/scripts/mcp-probe.mjs +22 -0
- package/templates/plugin-starter/scripts/setup.mjs +42 -0
- package/templates/plugin-starter/scripts/smoke.mjs +76 -0
- package/templates/plugin-starter/web/board.css +27 -0
- package/templates/plugin-starter/web/board.mjs +160 -0
- package/templates/plugin-starter/web/png.mjs +23 -0
- package/templates/provider-starter/LICENSE +21 -0
- package/templates/provider-starter/README.md +50 -0
- package/templates/provider-starter/index.d.mts +5 -0
- package/templates/provider-starter/index.mjs +165 -0
- package/templates/provider-starter/package.json +13 -0
- package/templates/provider-starter/scripts/core-cli.mjs +22 -0
- package/templates/provider-starter/scripts/environment.mjs +122 -0
- package/templates/provider-starter/scripts/fixture.mjs +54 -0
- package/templates/provider-starter/scripts/mcp-probe.mjs +21 -0
- package/templates/provider-starter/scripts/protocol-smoke.mjs +48 -0
- package/templates/provider-starter/scripts/setup.mjs +44 -0
- package/templates/provider-starter/scripts/smoke.mjs +145 -0
- package/user_guide.md +3 -3
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
import { readFile, readdir } from 'node:fs/promises';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { setTimeout as delay } from 'node:timers/promises';
|
|
5
|
+
import { createEnvironment, credentialEnv, syntheticKey } from './environment.mjs';
|
|
6
|
+
import { setup } from './setup.mjs';
|
|
7
|
+
import { runCore } from './core-cli.mjs';
|
|
8
|
+
import { mcpProbe } from './mcp-probe.mjs';
|
|
9
|
+
import { PNG } from './fixture.mjs';
|
|
10
|
+
|
|
11
|
+
const args = process.argv.slice(2);
|
|
12
|
+
assert(args.length === 0 || args.length === 2 && args[0] === '--proxy-url', 'Usage: node scripts/smoke.mjs [--proxy-url http://127.0.0.1:PORT]');
|
|
13
|
+
const env = await createEnvironment({ proxyUrl: args[1] }), checks = [];
|
|
14
|
+
const parsed = result => { assert(!result.isError, JSON.stringify(result)); return result.structuredContent ?? JSON.parse(result.content.find(item => item.type === 'text').text); };
|
|
15
|
+
const postCount = () => env.fixture.requests.filter(item => item.method === 'POST').length;
|
|
16
|
+
const prefix = '/api/v0/provider-management/';
|
|
17
|
+
async function continuation(runId) {
|
|
18
|
+
const view = await env.http('/api/v0/runs/' + runId);
|
|
19
|
+
const accepted = await env.http('/api/v0/runs/' + runId + '/continue', { key: crypto.randomUUID(), value: { expectedRevision: view.revision } }, 202);
|
|
20
|
+
return env.terminal(accepted.operation.id);
|
|
21
|
+
}
|
|
22
|
+
async function noCredentialFiles(directory) {
|
|
23
|
+
for (const item of await readdir(directory, { withFileTypes: true })) {
|
|
24
|
+
const file = path.join(directory, item.name);
|
|
25
|
+
if (item.isDirectory()) await noCredentialFiles(file);
|
|
26
|
+
else { const bytes = await readFile(file); assert(!bytes.includes(Buffer.from(syntheticKey)), 'synthetic provider credential persisted: ' + item.name); }
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
try {
|
|
30
|
+
const original = await readFile(env.prepared.providerConfigPath);
|
|
31
|
+
const options = { directory: env.prepared.directory, endpoint: env.fixture.origin, credentialEnv };
|
|
32
|
+
await assert.rejects(setup(options), { code: 'EEXIST' });
|
|
33
|
+
await assert.rejects(setup({ ...options, directory: path.resolve('private-demo') }), /outside the plugin project/);
|
|
34
|
+
assert.deepEqual(await readFile(env.prepared.providerConfigPath), original);
|
|
35
|
+
const originalConfig = JSON.parse(original).catalog ?? JSON.parse(original);
|
|
36
|
+
assert.equal(originalConfig.providers[0].apiKey, undefined);
|
|
37
|
+
assert.deepEqual(originalConfig.providers[0].models, []);
|
|
38
|
+
checks.push('new-directory setup rejects overwrite and package-local data; stores only the environment name with no enabled model pool');
|
|
39
|
+
|
|
40
|
+
await env.start({ key: '' });
|
|
41
|
+
let settings = await env.http(prefix + 'settings');
|
|
42
|
+
await env.http(prefix + 'discover', { value: { providerId: 'wan-reference', expectedRevision: settings.revision } }, 409);
|
|
43
|
+
assert.equal(env.fixture.requests.length, 0);
|
|
44
|
+
await env.stop(); await env.start();
|
|
45
|
+
settings = await env.http(prefix + 'settings');
|
|
46
|
+
assert(settings.protocols.some(item => item.id === 'example.wan-image.images'));
|
|
47
|
+
const discovered = await env.http(prefix + 'discover', { value: { providerId: 'wan-reference', expectedRevision: settings.revision } });
|
|
48
|
+
assert.equal(discovered.persisted, false); assert.deepEqual(discovered.models.map(item => item.id), ['wan2.6-t2i']);
|
|
49
|
+
assert.equal(env.fixture.requests.filter(item => item.path.startsWith('/api/v1/models')).length, 2);
|
|
50
|
+
assert.deepEqual(await readFile(env.prepared.providerConfigPath), original);
|
|
51
|
+
checks.push('actual Core CLI exposes the contributed protocol; missing credentials make zero requests; complete two-page directory is read without silently applying it');
|
|
52
|
+
|
|
53
|
+
const record = settings.providers[0];
|
|
54
|
+
const provider = Object.fromEntries(['id', 'name', 'baseUrl', 'mediaBaseUrl', 'mediaProtocol', 'enabled', 'auth'].map(field => [field, record[field]]));
|
|
55
|
+
provider.models = discovered.models;
|
|
56
|
+
settings = await env.http(prefix + 'save', { value: { expectedRevision: settings.revision, provider, credential: { action: 'keep' },
|
|
57
|
+
assignments: { 'image-gen': { mode: 'manual', models: ['wan-reference::wan2.6-t2i'] } } } });
|
|
58
|
+
const none = await env.connection([]), unselected = await mcpProbe(await env.exported(none));
|
|
59
|
+
assert(!(await unselected.request('tools/list', {})).tools.some(item => item.name === 'iris_core_create_generation'));
|
|
60
|
+
const connection = await env.connection(); let client = await mcpProbe(await env.exported(connection));
|
|
61
|
+
let names = (await client.request('tools/list', {})).tools.map(item => item.name);
|
|
62
|
+
assert(names.includes('iris_core_create_generation')); assert(!names.includes('iris_core_plugin_call')); assert(!names.includes('iris_core_create_video'));
|
|
63
|
+
checks.push('user explicitly applies the discovered model and manual pool; selecting image generation controls ordinary MCP media tools without a separate Provider tool whitelist');
|
|
64
|
+
|
|
65
|
+
const flows = [];
|
|
66
|
+
for (let i = 0; i < 2; i++) flows.push(parsed(await client.call('iris_core_create_generation', {
|
|
67
|
+
key: crypto.randomUUID(), modelRef: 'wan-reference::wan2.6-t2i', prompt: 'controlled local Provider starter ' + i
|
|
68
|
+
})).flow);
|
|
69
|
+
assert.equal(postCount(), 0);
|
|
70
|
+
const requests = flows.map(flow => ({ key: crypto.randomUUID(), runId: flow.id, expectedRevision: flow.revision }));
|
|
71
|
+
env.fixture.holdSubmits();
|
|
72
|
+
const accepted = await Promise.all(requests.map(value => client.call('iris_core_continue', value).then(parsed)));
|
|
73
|
+
const deadline = performance.now() + 5000;
|
|
74
|
+
while (postCount() < 2 && performance.now() < deadline) await delay(10);
|
|
75
|
+
env.fixture.releaseSubmits();
|
|
76
|
+
for (const value of accepted) assert.equal((await env.terminal(value.operation.id)).state, 'succeeded');
|
|
77
|
+
assert.equal(postCount(), 2); assert.equal(env.fixture.peak, 2);
|
|
78
|
+
const submitted = env.fixture.requests.filter(item => item.method === 'POST');
|
|
79
|
+
assert(submitted.every(item => item.async === 'enable' && JSON.parse(item.body).parameters.n === 1));
|
|
80
|
+
await env.stop();
|
|
81
|
+
const tasks = [];
|
|
82
|
+
for (const flow of flows) {
|
|
83
|
+
const view = await runCore(env.prepared.dataRoot, 'flow', 'inspect', flow.id);
|
|
84
|
+
const task = (await runCore(env.prepared.dataRoot, 'task', 'inspect', view.task.id)).task;
|
|
85
|
+
assert.equal(task.acceptance, 'accepted'); assert(env.fixture.tasks.has(task.remoteTaskId));
|
|
86
|
+
assert.equal(task.pluginDependency.pluginVersion, '0.1.0'); assert.equal(task.pluginDependency.contributionId, 'example.wan-image.images');
|
|
87
|
+
assert.deepEqual(task.pluginDependency, task.attempts[0].pluginDependency); tasks.push(task.id);
|
|
88
|
+
if (args.length) { assert.equal(task.semanticsVersion, 3); assert(task.networkRoutes.some(route => route.operation === 'submit' && route.nodeId === 'fixture-net')); }
|
|
89
|
+
}
|
|
90
|
+
checks.push('two real local HTTP submissions overlap under Core scheduling; public CLI reads accepted Task/Attempt with exact plugin identity and original remote IDs');
|
|
91
|
+
|
|
92
|
+
for (const selection of [{ present: false }, { version: '0.1.1' }]) {
|
|
93
|
+
await env.start(selection); const before = env.fixture.requests.length;
|
|
94
|
+
for (const flow of flows) {
|
|
95
|
+
const view = await env.http('/api/v0/runs/' + flow.id); assert(tasks.includes(view.task.id));
|
|
96
|
+
const result = await continuation(flow.id); assert.equal(result.state, 'failed', JSON.stringify(result));
|
|
97
|
+
}
|
|
98
|
+
assert.equal(env.fixture.requests.length, before, 'missing/mismatched plugin must not contact any upstream');
|
|
99
|
+
await env.stop();
|
|
100
|
+
}
|
|
101
|
+
checks.push('absent or differently versioned plugin keeps saved history readable and blocks continuation before any upstream request');
|
|
102
|
+
|
|
103
|
+
env.fixture.ready = true;
|
|
104
|
+
const rotated = syntheticKey + '-rotated'; await env.start({ key: rotated }); client = await mcpProbe(await env.exported(connection));
|
|
105
|
+
for (let i = 0; i < flows.length; i++) {
|
|
106
|
+
const view = parsed(await client.call('iris_core_run', { runId: flows[i].id }));
|
|
107
|
+
const operation = parsed(await client.call('iris_core_continue', { key: crypto.randomUUID(), runId: view.id, expectedRevision: view.revision })).operation;
|
|
108
|
+
assert.equal((await env.terminal(operation.id)).state, 'succeeded');
|
|
109
|
+
const delivered = parsed(await client.call('iris_core_run', { runId: view.id }));
|
|
110
|
+
assert.equal(delivered.task.id, tasks[i]); assert.equal(delivered.task.attemptCount, 1); assert.equal(delivered.task.deliveryState, 'ready');
|
|
111
|
+
const image = (await client.call('iris_core_image', { artifactId: delivered.output.artifactId })).content.find(item => item.type === 'image');
|
|
112
|
+
assert.deepEqual(Buffer.from(image.data, 'base64'), PNG);
|
|
113
|
+
}
|
|
114
|
+
assert.equal(postCount(), 2);
|
|
115
|
+
const polls = env.fixture.requests.filter(item => item.path.startsWith('/api/v1/tasks/'));
|
|
116
|
+
assert(polls.length >= 2 && polls.every(item => item.authorization === 'Bearer ' + rotated));
|
|
117
|
+
assert(env.fixture.requests.filter(item => item.cdn).every(item => item.authorization === undefined));
|
|
118
|
+
checks.push('restoring the exact plugin after restart uses the rotated environment value to poll original remote tasks and follow credential-free CDN redirects; no repeated POST');
|
|
119
|
+
|
|
120
|
+
env.fixture.mode = 'missing-id';
|
|
121
|
+
const ambiguous = (await env.http('/api/v0/generations', { key: crypto.randomUUID(), value: {
|
|
122
|
+
modelRef: 'wan-reference::wan2.6-t2i', prompt: 'controlled ambiguous response'
|
|
123
|
+
} }, 201)).flow;
|
|
124
|
+
await continuation(ambiguous.id);
|
|
125
|
+
let ambiguousView = await env.http('/api/v0/runs/' + ambiguous.id);
|
|
126
|
+
assert.equal(ambiguousView.task.acceptance, 'unknown'); assert.equal(ambiguousView.task.attemptCount, 1);
|
|
127
|
+
const ambiguousTask = ambiguousView.task.id, count = postCount(); assert.equal(count, 3);
|
|
128
|
+
await env.stop(); env.fixture.mode = 'normal'; await env.start({ key: rotated });
|
|
129
|
+
const requestCount = env.fixture.requests.length; await continuation(ambiguous.id);
|
|
130
|
+
ambiguousView = await env.http('/api/v0/runs/' + ambiguous.id);
|
|
131
|
+
assert.equal(ambiguousView.task.id, ambiguousTask); assert.equal(ambiguousView.task.acceptance, 'unknown');
|
|
132
|
+
assert.equal(env.fixture.requests.length, requestCount); assert.equal(postCount(), count);
|
|
133
|
+
checks.push('a submission without remote identity persists unknown acceptance; restart and explicit continuation neither retry POST nor invent a poll ID');
|
|
134
|
+
|
|
135
|
+
await env.reduce(connection); client = await mcpProbe(await env.exported(connection));
|
|
136
|
+
names = (await client.request('tools/list', {})).tools.map(item => item.name);
|
|
137
|
+
assert(!names.includes('iris_core_continue')); assert(!names.includes('iris_core_create_generation'));
|
|
138
|
+
assert.equal(parsed(await client.call('iris_core_run', { runId: flows[0].id })).task.deliveryState, 'ready');
|
|
139
|
+
await assert.rejects(client.call('iris_core_continue', requests[0]), /Tool iris_core_continue not found/);
|
|
140
|
+
assert.equal(postCount(), count); checks.push('reducing connection authority removes and rejects new execution while retaining authorized original history');
|
|
141
|
+
await env.stop(); await noCredentialFiles(env.prepared.directory); assert.deepEqual(env.fixture.errors, []);
|
|
142
|
+
checks.push('normal CLI SIGTERM completes across restarts; provider credentials are absent from Core records, provider configuration and backups');
|
|
143
|
+
console.log(JSON.stringify({ ok: true, work: env.work, checks, taskIds: tasks, paidCalls: 0, submits: postCount(), peakHttp: env.fixture.peak,
|
|
144
|
+
proxy: args.length ? 'explicit-loopback-CONNECT' : 'inherit' }, null, 2));
|
|
145
|
+
} finally { await env.close(); }
|
package/user_guide.md
CHANGED
|
@@ -64,9 +64,9 @@ DSH 已配好同一媒体服务时,可在第 1 步选择连接来源,明确
|
|
|
64
64
|
|
|
65
65
|
保存供应商和修改能力分配都会立即生效,不需要重启 DSH。
|
|
66
66
|
|
|
67
|
-
## ComfyUI
|
|
67
|
+
## ComfyUI 工作台(0.3 beta)
|
|
68
68
|
|
|
69
|
-
npm 0.2.7
|
|
69
|
+
稳定npm 0.2.7尚不含此界面;安装0.3.0-beta.1后可在“+ 添加供应商”选择“ComfyUI · 已有服务”,保存地址/认证后导入 API 图或 Iris 参数模板,明确节点和公开参数;检查、保存不生成图片。画图时选择具体工作流,可调整 LoRA 双权重、种子等声明参数,并从只读检查取得可用选项。Iris 不安装 ComfyUI 或模型,静态检查不等于真实 GPU 验收。完整操作与限制见 [DSH ComfyUI 入口](docs/IMAGE_GENERATION.md#dsh-工作台入口03-alpha)。
|
|
70
70
|
|
|
71
71
|
## 供应商与协议
|
|
72
72
|
|
|
@@ -224,7 +224,7 @@ $DSH_HOME/iris/v1/providers.json
|
|
|
224
224
|
|
|
225
225
|
`mediaBaseUrl` 可以省略或留空,此时媒体调用沿用 `baseUrl`。`assignments` 可以省略,但从 0.2.4 起缺失分配不发起对应功能的新调用;0.2.6 也不会将其静默改为自动池。包含特殊字符的 provider 或模型引用会经过 URL 编码,复杂引用建议在工作台中生成,不要手写。
|
|
226
226
|
|
|
227
|
-
可为明确不需要认证的本地端点设置 `"auth": "none"` 并省略 `apiKey`;缺省或 `"auth": "bearer"` 仍要求 Key,保持旧配置行为。无认证模式不会发送 Authorization 头,已有的旧 Key 也不会被带入该模式的媒体请求。0.2.7
|
|
227
|
+
可为明确不需要认证的本地端点设置 `"auth": "none"` 并省略 `apiKey`;缺省或 `"auth": "bearer"` 仍要求 Key,保持旧配置行为。无认证模式不会发送 Authorization 头,已有的旧 Key 也不会被带入该模式的媒体请求。0.2.7 工作台尚无专门的无认证开关,需按上述停机原则编辑私有配置;beta.1已在添加供应商与认证设置中提供选择。不要对需要认证的公网端点使用 `auth:none`。
|
|
228
228
|
|
|
229
229
|
API Key 以明文保存在宿主侧的 `providers.json` 中。POSIX 上 Iris 目录为 `0700`、文件为 `0600`,0.1.1 首次启动会收紧既有 Iris 树但不修改内容或跟随符号链接;Windows 的 mode 不能替代 ACL。状态接口和界面只返回掩码,不会显示完整 Key。不要把这个文件提交到版本库或发给他人。
|
|
230
230
|
|