@ai-workbench/remote-agent 0.8.19 → 0.8.23
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 +27 -134
- package/dist/acp.d.ts +23 -16
- package/dist/acp.js +209 -226
- package/dist/agents.d.ts +0 -1
- package/dist/agents.js +2 -2
- package/dist/broker-runtime.d.ts +3 -5
- package/dist/broker-runtime.js +45 -342
- package/dist/broker.d.ts +6 -31
- package/dist/broker.js +42 -113
- package/dist/catalog-ssh.d.ts +2 -31
- package/dist/catalog-ssh.js +9 -39
- package/dist/claude-local.d.ts +1 -1
- package/dist/claude-local.js +41 -105
- package/dist/client.js +34 -126
- package/dist/close-diagnostics.d.ts +6 -20
- package/dist/close-diagnostics.js +13 -57
- package/dist/connect-contract.d.ts +4 -8
- package/dist/conversation-details.d.ts +0 -29
- package/dist/conversation-details.js +8 -99
- package/dist/employee-endpoint.d.ts +1 -1
- package/dist/employee-endpoint.js +21 -19
- package/dist/employee-exec.d.ts +4 -3
- package/dist/employee-exec.js +25 -13
- package/dist/employee-info.d.ts +7 -1
- package/dist/employee-info.js +24 -3
- package/dist/employee-location.js +3 -4
- package/dist/employee-mcp.js +44 -69
- package/dist/employee-native.d.ts +1 -3
- package/dist/employee-native.js +6 -27
- package/dist/employee-presentation.d.ts +0 -5
- package/dist/employee-presentation.js +0 -15
- package/dist/employee-provider.d.ts +3 -11
- package/dist/employee-provider.js +69 -205
- package/dist/employee-reasons.js +1 -5
- package/dist/employee-shell.d.ts +2 -1
- package/dist/employee-shell.js +10 -13
- package/dist/employee-ssh.d.ts +1 -3
- package/dist/employee-ssh.js +13 -16
- package/dist/employee-tools.d.ts +5 -5
- package/dist/failure-evidence.d.ts +2 -10
- package/dist/failure-evidence.js +12 -61
- package/dist/host-workspace.d.ts +4 -2
- package/dist/host-workspace.js +6 -2
- package/dist/index.d.ts +13 -43
- package/dist/index.js +192 -484
- package/dist/input.js +2 -3
- package/dist/local-user-turn.js +5 -6
- package/dist/mapping.d.ts +5 -3
- package/dist/mapping.js +31 -36
- package/dist/model-catalog.d.ts +2 -41
- package/dist/model-catalog.js +24 -282
- package/dist/model-configuration.d.ts +0 -3
- package/dist/model-configuration.js +8 -47
- package/dist/model-presentation.d.ts +1 -0
- package/dist/model-presentation.js +2 -2
- package/dist/permissions.d.ts +15 -0
- package/dist/permissions.js +30 -0
- package/dist/preflight-diagnostic.js +11 -22
- package/dist/preflight-payload.d.ts +1 -1
- package/dist/preflight-payload.js +2 -2
- package/dist/presentation.js +21 -41
- package/dist/provider.d.ts +12 -34
- package/dist/provider.js +17 -92
- package/dist/readiness.js +1 -7
- package/dist/remote-details.d.ts +41 -17
- package/dist/remote-details.js +84 -381
- package/dist/workspace-source.d.ts +1 -25
- package/dist/workspace-source.js +1 -138
- package/package.json +11 -12
- package/dist/catalog-diagnostics.d.ts +0 -16
- package/dist/catalog-diagnostics.js +0 -108
- package/dist/host-layout.d.ts +0 -8
- package/dist/host-layout.js +0 -9
- package/dist/job.d.ts +0 -17
- package/dist/job.js +0 -57
- package/dist/model-defaults.d.ts +0 -29
- package/dist/model-defaults.js +0 -62
- package/dist/oneshot.d.ts +0 -13
- package/dist/oneshot.js +0 -78
- package/dist/protocol-boundary.d.ts +0 -13
- package/dist/protocol-boundary.js +0 -49
- package/dist/provider-locale.d.ts +0 -19
- package/dist/provider-locale.js +0 -73
- package/dist/recovery-checkpoint.d.ts +0 -6
- package/dist/recovery-checkpoint.js +0 -71
- package/dist/recovery.d.ts +0 -51
- package/dist/recovery.js +0 -61
- package/dist/sdk-ssh-wrapper.d.ts +0 -2
- package/dist/sdk-ssh-wrapper.js +0 -34
- package/dist/stage-timing.d.ts +0 -31
- package/dist/stage-timing.js +0 -61
- package/dist/workspace-notice.d.ts +0 -47
- package/dist/workspace-notice.js +0 -273
- package/dist/workspace-source-confirmation.d.ts +0 -4
- package/dist/workspace-source-confirmation.js +0 -12
|
@@ -168,30 +168,15 @@ export class ModelConfiguration {
|
|
|
168
168
|
fail(error) {
|
|
169
169
|
this.state = freeze({ ...this.state, confirmed: false, failure: { code: error.code, message: error.message } });
|
|
170
170
|
}
|
|
171
|
-
checkAckRevision(revision, stage) {
|
|
172
|
-
if (revision !== this.revision)
|
|
173
|
-
unavailable(`${stage}回执之后收到其他配置更新,原选择未获确认`);
|
|
174
|
-
}
|
|
175
171
|
async set(id, value, stage) {
|
|
176
|
-
const revision = this.revision, modelId = this.parsed?.model.id, effortId = this.parsed?.effort?.id;
|
|
177
|
-
let response;
|
|
178
172
|
try {
|
|
179
|
-
response = await this.rpcSet(id, value);
|
|
173
|
+
const response = await this.rpcSet(id, value);
|
|
174
|
+
if (record(response) && Array.isArray(response.configOptions))
|
|
175
|
+
this.apply(this.prepare(response.configOptions));
|
|
180
176
|
}
|
|
181
177
|
catch (cause) {
|
|
182
|
-
throw new ModelConfigurationError(`${stage}
|
|
178
|
+
throw new ModelConfigurationError(`${stage}配置请求失败`, { cause });
|
|
183
179
|
}
|
|
184
|
-
if (!record(response) || !Array.isArray(response.configOptions))
|
|
185
|
-
unavailable(`${stage}配置回执缺少完整配置列表`);
|
|
186
|
-
const prepared = this.prepare(response.configOptions);
|
|
187
|
-
if (prepared.parsed.model.id !== modelId || stage === '推理等级' && prepared.parsed.effort && prepared.parsed.effort.id !== effortId)
|
|
188
|
-
unavailable('配置回执改用了其他入口,原请求没有得到确认');
|
|
189
|
-
// Notifications can precede their own setter ACK. Only a conflicting real
|
|
190
|
-
// selection, rather than unrelated/same-value UI updates, invalidates it.
|
|
191
|
-
if (revision !== this.revision && !sameSelection(this.parsed, prepared.parsed))
|
|
192
|
-
unavailable(`${stage}配置请求期间收到不同的实际配置,无法确认回执顺序`);
|
|
193
|
-
this.apply(prepared);
|
|
194
|
-
return this.revision;
|
|
195
180
|
}
|
|
196
181
|
async select(model, effort) {
|
|
197
182
|
if (this.busy)
|
|
@@ -203,25 +188,10 @@ export class ModelConfiguration {
|
|
|
203
188
|
unavailable('当前远端配置列表无效');
|
|
204
189
|
if (!this.parsed.model.values.some(entry => entry.value === model))
|
|
205
190
|
this.inform('PICKER_INCOMPLETE');
|
|
206
|
-
|
|
207
|
-
this.
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
if (effort !== undefined) {
|
|
211
|
-
const selector = this.parsed?.effort;
|
|
212
|
-
if (!selector)
|
|
213
|
-
unavailable('远端没有提供实际推理等级选择器');
|
|
214
|
-
if (!selector.values.some(entry => entry.value === effort))
|
|
215
|
-
this.inform('PICKER_INCOMPLETE');
|
|
216
|
-
ackRevision = await this.set(selector.id, effort, '推理等级');
|
|
217
|
-
this.checkAckRevision(ackRevision, '推理等级');
|
|
218
|
-
if (this.state.model !== model)
|
|
219
|
-
unavailable('推理等级回执中的模型发生变化');
|
|
220
|
-
if (!this.state.effortAvailable || this.state.effort !== effort)
|
|
221
|
-
unavailable('推理等级配置回执与所选等级不一致');
|
|
222
|
-
}
|
|
223
|
-
this.checkAckRevision(ackRevision, '选择');
|
|
224
|
-
this.state = freeze({ ...this.state, confirmed: true });
|
|
191
|
+
await this.set(this.parsed.model.id, model, '模型');
|
|
192
|
+
if (effort !== undefined && this.parsed?.effort)
|
|
193
|
+
await this.set(this.parsed.effort.id, effort, '推理等级');
|
|
194
|
+
this.state = freeze({ ...this.state, confirmed: this.state.model === model && (effort === undefined || this.state.effort === effort) });
|
|
225
195
|
return this.state;
|
|
226
196
|
}
|
|
227
197
|
catch (cause) {
|
|
@@ -233,13 +203,4 @@ export class ModelConfiguration {
|
|
|
233
203
|
this.busy = false;
|
|
234
204
|
}
|
|
235
205
|
}
|
|
236
|
-
/** Call immediately before prompt; an idle/new/load/resume update withdraws the ACK. */
|
|
237
|
-
assertSelection(model, effort) {
|
|
238
|
-
if (this.busy || !this.parsed || !this.state.confirmed)
|
|
239
|
-
unavailable('当前模型选择尚未获得完整远端确认');
|
|
240
|
-
if (this.state.model !== model)
|
|
241
|
-
unavailable('当前实际模型与待发送选择不一致');
|
|
242
|
-
if (effort !== undefined && (!this.state.effortAvailable || this.state.effort !== effort))
|
|
243
|
-
unavailable('当前实际推理等级与待发送选择不一致');
|
|
244
|
-
}
|
|
245
206
|
}
|
|
@@ -4,6 +4,7 @@ import { type CatalogLease, type HostModel } from './model-catalog.ts';
|
|
|
4
4
|
export declare class ModelPresentation {
|
|
5
5
|
private snapshot?;
|
|
6
6
|
remember(catalog: CatalogLease): void;
|
|
7
|
+
find(id: string): HostModel | undefined;
|
|
7
8
|
resolve(provider: string, id: string): (LlmResolvedModelInfo & {
|
|
8
9
|
catalog: HostModel;
|
|
9
10
|
}) | undefined;
|
|
@@ -2,12 +2,12 @@ import { modelInfo } from "./model-catalog.js";
|
|
|
2
2
|
/** One displayed directory, never an execution/admission cache. No clock or TTL. */
|
|
3
3
|
export class ModelPresentation {
|
|
4
4
|
snapshot;
|
|
5
|
-
remember(catalog) {
|
|
5
|
+
remember(catalog) { this.snapshot = { models: structuredClone(catalog.models) }; }
|
|
6
|
+
find(id) { return this.snapshot?.models.find(row => row.id === id); }
|
|
6
7
|
resolve(provider, id) {
|
|
7
8
|
const snapshot = this.snapshot, model = snapshot?.models.find(row => row.id === id);
|
|
8
9
|
if (!model)
|
|
9
10
|
return;
|
|
10
|
-
snapshot.assertCurrent();
|
|
11
11
|
return modelInfo(provider, structuredClone(model));
|
|
12
12
|
}
|
|
13
13
|
clear() { this.snapshot = undefined; }
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
2
|
+
export interface DshPermissions {
|
|
3
|
+
sandbox: 'read-only' | 'workspace-write' | 'danger-full-access';
|
|
4
|
+
approval: 'ask' | 'never';
|
|
5
|
+
preset?: 'auto';
|
|
6
|
+
}
|
|
7
|
+
export interface PermissionSource {
|
|
8
|
+
read(sessionId: string | undefined): DshPermissions;
|
|
9
|
+
subscribe(sessionId: string, changed: () => void): () => void;
|
|
10
|
+
}
|
|
11
|
+
/** Read effective official knobs. Never infer privileges from a prompt or a label. */
|
|
12
|
+
export declare function readDshPermissions(ctx: Pick<Context, 'get'>, sessionId: string | undefined): DshPermissions;
|
|
13
|
+
export declare function dshPermissionSource(ctx: Context): PermissionSource;
|
|
14
|
+
/** Three native mappings approved by orchestration on 2026-10-24. */
|
|
15
|
+
export declare function permissionMode(brand: 'claude' | 'codex', policy: DshPermissions): string;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { SessionId } from '@deepseek-ai/dsh-session';
|
|
2
|
+
import { NeedError } from "./remote.js";
|
|
3
|
+
const required = () => new NeedError('PERMISSION_POLICY_REQUIRED', '我需要读取当前会话的DSH权限设置,才能按你选择的权限执行。', '官方会话、sandboxPolicy和approval公开服务');
|
|
4
|
+
/** Read effective official knobs. Never infer privileges from a prompt or a label. */
|
|
5
|
+
export function readDshPermissions(ctx, sessionId) {
|
|
6
|
+
const session = sessionId ? ctx.get('sessions')?.get(SessionId(sessionId)) : undefined;
|
|
7
|
+
const sandbox = ctx.get('sandboxPolicy'), approval = ctx.get('approval');
|
|
8
|
+
if (!session || !sandbox || !approval || typeof sandbox.resolve !== 'function' || typeof approval.overrideOf !== 'function')
|
|
9
|
+
throw required();
|
|
10
|
+
// This is the official ApprovalService.effectivePolicy default, not a
|
|
11
|
+
// plugin-specific privilege fallback. It never implies automatic approval.
|
|
12
|
+
const mode = sandbox.resolve({ session }).mode, policy = approval.overrideOf(session) ?? approval.config.policy ?? 'ask';
|
|
13
|
+
if (!['read-only', 'workspace-write', 'danger-full-access'].includes(mode) || !['ask', 'never'].includes(policy))
|
|
14
|
+
throw required();
|
|
15
|
+
const presets = ctx.get('permissionPresets');
|
|
16
|
+
return { sandbox: mode, approval: policy, ...(presets?.current?.(session) === 'auto' ? { preset: 'auto' } : {}) };
|
|
17
|
+
}
|
|
18
|
+
export function dshPermissionSource(ctx) {
|
|
19
|
+
return { read: id => readDshPermissions(ctx, id), subscribe: (id, changed) => ctx.on('session/event', (session, event) => {
|
|
20
|
+
if (session.id === id && ['permission/preset', 'sandbox/mode', 'approval/policy'].includes(event.type))
|
|
21
|
+
changed();
|
|
22
|
+
}) };
|
|
23
|
+
}
|
|
24
|
+
/** Three native mappings approved by orchestration on 2026-10-24. */
|
|
25
|
+
export function permissionMode(brand, policy) {
|
|
26
|
+
if (policy.preset === 'auto' || policy.sandbox === 'danger-full-access' && policy.approval !== 'never')
|
|
27
|
+
throw new NeedError('PERMISSION_MODE_UNSUPPORTED', '这个DSH权限组合还没有对应的远程执行模式;我需要主机连接组件支持该组合。', 'sandbox=' + policy.sandbox + '; approval=' + policy.approval + '; preset=' + (policy.preset ?? 'custom'));
|
|
28
|
+
return brand === 'claude' ? (policy.sandbox === 'read-only' ? 'plan' : policy.sandbox === 'workspace-write' ? 'default' : 'bypassPermissions') :
|
|
29
|
+
policy.sandbox === 'danger-full-access' ? 'agent-full-access' : policy.sandbox;
|
|
30
|
+
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { failureEvidenceSummary, primaryFailureCode } from "./close-diagnostics.js";
|
|
2
2
|
import { SessionId } from '@deepseek-ai/dsh-session';
|
|
3
3
|
import { LlmError } from '@deepseek-ai/dsh-llm';
|
|
4
|
-
import { isDeepStrictEqual } from 'node:util';
|
|
5
4
|
import { NeedError } from "./remote.js";
|
|
6
5
|
import { ModelConfigurationError } from "./model-configuration.js";
|
|
7
6
|
import { officialEmployeeWorkspace } from "./employee-workspace.js";
|
|
@@ -19,12 +18,11 @@ export function createPreflightDiagnostics(options) {
|
|
|
19
18
|
const scopes = new WeakMap();
|
|
20
19
|
function capture(sessionId, position) {
|
|
21
20
|
const api = options.getApi();
|
|
22
|
-
let connection, session,
|
|
21
|
+
let connection, session, source = unknownSource();
|
|
23
22
|
let context = position ? { ...position } : { turn: null, step: null };
|
|
24
23
|
try {
|
|
25
24
|
connection = api?.getConnectionState();
|
|
26
25
|
session = sessionId ? options.ctx.get('sessions')?.get(SessionId(sessionId)) : undefined;
|
|
27
|
-
header = session && structuredClone(session.header);
|
|
28
26
|
if (!position)
|
|
29
27
|
for (const event of session?.snapshotEvents() ?? []) {
|
|
30
28
|
if (event.type === 'turn/start')
|
|
@@ -51,39 +49,30 @@ export function createPreflightDiagnostics(options) {
|
|
|
51
49
|
const rows = state?.items.filter(row => row.workspaceId === workspace.id) ?? [];
|
|
52
50
|
if (state?.phase === 'ready' && state.instanceId === connection?.instanceId && state.epoch === connection.epoch && rows.length === 1) {
|
|
53
51
|
const row = rows[0];
|
|
54
|
-
source = { workspaceId: row.workspaceId, bindingId: row.bindingId, source: row.source, status: row.status };
|
|
52
|
+
source = { workspaceId: row.workspaceId, bindingId: row.bindingId, source: row.source === 'local' || row.source === 'host' ? row.source : null, status: row.status };
|
|
55
53
|
}
|
|
56
54
|
}
|
|
57
55
|
}
|
|
58
56
|
}
|
|
59
|
-
catch
|
|
60
|
-
|
|
57
|
+
catch {
|
|
58
|
+
console.warn('[remote-agent] 预检日志上下文未读取');
|
|
61
59
|
}
|
|
62
|
-
|
|
63
|
-
if (captureError !== undefined)
|
|
64
|
-
throw Object.assign(new NeedError('REMOTE_DETAIL_SCOPE_INVALID', '连接前诊断上下文无法核对。', '真实官方会话与连接快照'), { cause: captureError });
|
|
65
|
-
if (!sessionId || !session || options.ctx.get('sessions')?.get(SessionId(sessionId)) !== session || !isDeepStrictEqual(session.header, header))
|
|
66
|
-
throw new NeedError('REMOTE_DETAIL_SCOPE_INVALID', '连接前诊断所属会话已变化。', '原官方session/header');
|
|
67
|
-
};
|
|
68
|
-
return { sessionId, binding: { api, connection }, context, source, assertScope };
|
|
60
|
+
return { sessionId, binding: { api, connection }, context, source };
|
|
69
61
|
}
|
|
70
62
|
const scopeFor = (request) => { let scope = scopes.get(request); if (!scope) {
|
|
71
63
|
scope = capture(request.sessionId);
|
|
72
64
|
scopes.set(request, scope);
|
|
73
65
|
} return scope; };
|
|
74
|
-
const write = (scope, provider, observation) => options.manager().recordPreflightCheck({ sessionId: scope.sessionId, provider, observation, context: scope.context, binding: scope.binding
|
|
66
|
+
const write = (scope, provider, observation) => options.manager().recordPreflightCheck({ sessionId: scope.sessionId, provider, observation, context: scope.context, binding: scope.binding });
|
|
75
67
|
async function record(request, provider, observation) {
|
|
76
68
|
const scope = scopeFor(request), payload = observation.payload;
|
|
77
69
|
if (validPreflightPayload(payload) && ['failed', 'declined', 'cancelled'].includes(payload.outcome))
|
|
78
70
|
request.preflightFailureRecorded = true;
|
|
79
71
|
try {
|
|
80
72
|
await write(scope, provider, observation);
|
|
81
|
-
if (validPreflightPayload(payload) && payload.outcome === 'confirmed')
|
|
82
|
-
scope.source = { workspaceId: payload.workspaceId, bindingId: payload.bindingId, source: payload.source, status: payload.status };
|
|
83
73
|
}
|
|
84
|
-
catch
|
|
85
|
-
|
|
86
|
-
throw error;
|
|
74
|
+
catch {
|
|
75
|
+
console.warn('[remote-agent] 预检诊断未保存');
|
|
87
76
|
}
|
|
88
77
|
}
|
|
89
78
|
return {
|
|
@@ -96,8 +85,8 @@ export function createPreflightDiagnostics(options) {
|
|
|
96
85
|
try {
|
|
97
86
|
await record(request, provider, { kind: 'need', severity: 'action-required', code, summary: '本轮在连接前准备阶段停止;原始请求保留,未重发。' + failureEvidenceSummary(error), payload: { phase: 'workspace-source-admission', stage, ...scope.source, outcome: code === 'ABORTED' ? 'cancelled' : 'failed' } });
|
|
98
87
|
}
|
|
99
|
-
catch
|
|
100
|
-
|
|
88
|
+
catch {
|
|
89
|
+
console.warn('[remote-agent] 预检诊断未保存');
|
|
101
90
|
}
|
|
102
91
|
},
|
|
103
92
|
forPreparation(sessionId, context) {
|
|
@@ -4,7 +4,7 @@ export interface PreflightPayload {
|
|
|
4
4
|
stage: SourceAdmissionStage;
|
|
5
5
|
workspaceId: string | null;
|
|
6
6
|
bindingId: string | null;
|
|
7
|
-
source: 'local' | 'host' |
|
|
7
|
+
source: 'local' | 'host' | null;
|
|
8
8
|
status: 'unselected' | 'selected' | 'legacy-confirmation-required' | 'invalid' | null;
|
|
9
9
|
outcome: 'confirmation-required' | 'confirmed' | 'declined' | 'cancelled' | 'failed';
|
|
10
10
|
}
|
|
@@ -4,8 +4,8 @@ export function validPreflightPayload(value) {
|
|
|
4
4
|
const p = value, keys = ['phase', 'stage', 'workspaceId', 'bindingId', 'source', 'status', 'outcome'];
|
|
5
5
|
const id = (v) => v === null || typeof v === 'string' && v.length > 0 && !/[\x00-\x1f\x7f]/.test(v);
|
|
6
6
|
return Object.keys(p).length === keys.length && keys.every(key => Object.hasOwn(p, key)) && p.phase === 'workspace-source-admission'
|
|
7
|
-
&& ['source-context', '
|
|
8
|
-
&& id(p.workspaceId) && id(p.bindingId) && [null, 'local', 'host'
|
|
7
|
+
&& ['source-context', 'input-acceptance', 'login-readiness', 'local-admission', 'input-prepare', 'model-catalog', 'runtime-resolve'].includes(p.stage)
|
|
8
|
+
&& id(p.workspaceId) && id(p.bindingId) && [null, 'local', 'host'].includes(p.source)
|
|
9
9
|
&& [null, 'unselected', 'selected', 'legacy-confirmation-required', 'invalid'].includes(p.status)
|
|
10
10
|
&& ['confirmation-required', 'confirmed', 'declined', 'cancelled', 'failed'].includes(p.outcome);
|
|
11
11
|
}
|
package/dist/presentation.js
CHANGED
|
@@ -5,35 +5,31 @@ export const TEST_HOST_NOTICE = '远程主机正在使用测试配置,遇到
|
|
|
5
5
|
/** Employee failures use business language; diagnostic codes remain separately available. */
|
|
6
6
|
export function employeeFailure(code, brand = 'codex') {
|
|
7
7
|
const messages = {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
PERMISSION_POLICY_REQUIRED: '我需要读取这条对话的权限设置,目前没有读到;本轮未执行,你的原话仍保留。',
|
|
9
|
+
PERMISSION_MODE_UNSUPPORTED: '这个权限档位还没有对应的远程执行能力;我需要主机连接组件支持该档位,本轮未执行,你的原话仍保留。',
|
|
10
|
+
PERMISSION_MODE_UNCONFIRMED: '远端没有确认按当前权限执行,本轮未继续;你的原话仍保留,具体原因见技术详情。',
|
|
11
|
+
PERMISSION_MODE_CHANGED: '远端权限已超出本会话选择,本次未发送;你的原话仍保留,具体原因见技术详情。',
|
|
12
|
+
CLAUDE_BYPASS_UNAVAILABLE: '主机没有为本会话开放完全权限,本轮未发送;我需要主机允许完全权限模式。',
|
|
13
|
+
PERMISSION_POLICY_CHANGED: '当前权限已变化或无法核对,这次派发已停止;没有自动重发,你的原话仍保留,在途结果请查看技术详情。',
|
|
14
|
+
APPROVAL_STALE: '连接或权限已变化,原审批已失效;没有自动重发,在途结果请查看技术详情。',
|
|
12
15
|
PROJECT_BINDING_INVALID: '文件来源已改,请新建会话继续;原会话历史仍可查看。',
|
|
13
16
|
WORKSPACE_LOCATION_REQUIRED: '我需要你确认这个工作区使用哪一个文件夹,本轮未执行;你的原话仍保留。',
|
|
14
17
|
WORKSPACE_LOCATION_CONFLICT: '工作区来源选择已更新,本次确认不能覆盖新的选择;本轮未执行,你的原话仍保留。',
|
|
15
18
|
LOCAL_USER_TURN_CHANGED: '本次输入已变化,本轮已停止,请确认对话后重新发送。',
|
|
16
19
|
LOCAL_USER_TURN_UNCONFIRMED: '无法核对本次员工输入,本轮已停止;请在当前会话重新发送。',
|
|
17
|
-
|
|
18
|
-
MODEL_CATALOG_REVOKED: '所选型号已不在当前主机目录中,本轮已停止;请在模型菜单核对选择。',
|
|
19
|
-
MODEL_CATALOG_SCOPE_CHANGED: '远程主机连接或可信目标已改变,本轮已停止;原输入没有自动重发。',
|
|
20
|
-
CONVERSATION_DETAILS_FAILED: '本轮已停止,技术详情保存未确认;下方分别列出运行与保存原因。',
|
|
21
|
-
TECHNICAL_DETAILS_UNAVAILABLE: '技术详情暂不可用,请更新远程主机连接组件。',
|
|
22
|
-
REMOTE_DETAIL_STORAGE_FAILED: '技术详情保存失败,本轮已停止,请联系管理员检查。',
|
|
23
|
-
REMOTE_DETAIL_DELIVERY_UNKNOWN: '技术详情的持久结果无法核对,本轮已停止。',
|
|
24
|
-
REMOTE_DETAIL_SCOPE_INVALID: '无法核对本次输入与当前会话的关联,本轮已停止;请联系管理员核对技术详情。',
|
|
20
|
+
AW_EMPLOYEE_ENVIRONMENTS_CONFIG_UNSUPPORTED: '主机环境配置会覆盖本机执行位置,本轮已停止;请联系管理员调整后在原会话重试。',
|
|
25
21
|
EMPLOYEE_CONTEXT_UNAVAILABLE: '我需要远程主机连接组件提供当前本机工作区,本轮未执行。',
|
|
26
22
|
EMPLOYEE_ENDPOINT_UNAVAILABLE: '我需要员工电脑的执行连接就绪,本轮未执行;请联系管理员检查连接组件。',
|
|
27
|
-
EMPLOYEE_CONTEXT_CHANGED: '
|
|
23
|
+
EMPLOYEE_CONTEXT_CHANGED: '本机文件夹或连接已变化,本轮已停止;恢复后可在原会话继续。',
|
|
28
24
|
EMPLOYEE_WORKSPACE_INVALID: '无法核对这条对话所属的本机文件夹,本轮未执行;请在工作区中重新打开对话。',
|
|
29
|
-
REMOTE_DETAIL_TOO_LARGE: '技术详情超过已配置的单事件容量,本轮已停止;请联系管理员调整conversationDetails.maxEventBytes。',
|
|
30
25
|
DEPENDENCY_REQUIRED: CONNECTION_REQUIRED,
|
|
26
|
+
MODEL_CATALOG_UNAVAILABLE: '所选型号暂时不可用,请打开模型菜单重新选择后再发送。',
|
|
31
27
|
LOGIN_REQUIRED: '需要登录,请到设置 → 远程主机连接 点登录',
|
|
32
28
|
LOGIN_COMPLETED: '登录已完成,请重新发送本轮内容。',
|
|
33
29
|
LOGIN_FAILED: '登录未完成,请到设置 → 远程主机连接 点登录;如仍有问题,请联系管理员。',
|
|
34
30
|
AUTH_STATUS_INVALID: '登录检查没有返回有效结果,请重新检查;如仍有问题,请联系管理员。',
|
|
35
31
|
HOST_OFFLINE: '暂时无法连接远程主机,请联系管理员。',
|
|
36
|
-
CONNECTION_LOST: '
|
|
32
|
+
CONNECTION_LOST: '远程主机连接已中断;请检查网络,恢复后可在原会话继续。',
|
|
37
33
|
SETTINGS_REQUIRED: '远程主机连接尚未设置好,请联系管理员。',
|
|
38
34
|
CONNECT_API_MISMATCH: '远程主机连接组件需要更新,请联系管理员。',
|
|
39
35
|
ENROLLMENT_REQUIRED: '我需要连接资料,请联系管理员发放。',
|
|
@@ -45,47 +41,31 @@ export function employeeFailure(code, brand = 'codex') {
|
|
|
45
41
|
HOST_TRUST_REQUIRED: '远程主机连接信息还未准备好,请联系管理员。',
|
|
46
42
|
POLICY_DENIED: '这个账号暂时不能使用,请联系公司账号管理员。',
|
|
47
43
|
SESSION_CONTEXT_MISMATCH: '远程主机连接已改变,请重新开始本次检查。',
|
|
48
|
-
ABORTED: '
|
|
44
|
+
ABORTED: '本轮已停止。操作可能已部分执行,请先确认文件;恢复连接后可在原会话继续。',
|
|
49
45
|
CONFIRMATION_REQUIRED: '请先选择是否打开授权窗口。',
|
|
50
46
|
CONTEXT_UNSUPPORTED: '远程 Codex 暂不支持这类会话内容,请联系管理员。',
|
|
51
47
|
CONTENT_UNSUPPORTED: '远程 Codex 暂不支持这类附件,请联系管理员。',
|
|
52
|
-
SYSTEM_PROMPT_UPDATE_PENDING: 'Claude原会话无法保证立即应用已变化的系统或开发者要求,本轮未发送;请新建会话应用新要求。',
|
|
53
|
-
SYSTEM_PROMPT_UNSUPPORTED: '远端没有声明系统与开发者上下文能力,本轮未发送;需要管理员提供支持该能力的远端适配器。',
|
|
54
48
|
SYSTEM_CONTEXT_TYPE_UNSUPPORTED: '系统或开发者要求包含暂不支持的非文本内容,本轮未新建或发送;请使用文本要求或联系管理员。',
|
|
55
|
-
RECOVERY_CONTEXT_POLICY_UNSUPPORTED: '旧版会话恢复记录仍绑定模型要求,无法安全接回;本轮未发送,请联系管理员核对原会话。',
|
|
56
|
-
SYSTEM_PROMPT_POLICY_UNSUPPORTED: '远端还不支持保留原会话并按新要求继续,请联系管理员更新远端适配器;本轮未发送。',
|
|
57
|
-
SYSTEM_PROMPT_NEW_SESSION_REQUIRED: '会话要求已变化,需要新建 Codex 会话并承接历史后继续;本轮未发送。',
|
|
58
|
-
SESSION_CONTEXT_DIGEST_INVALID: '原会话的要求记录无法核对,本轮未发送;请联系管理员核对原会话。',
|
|
59
49
|
HISTORY_CONTENT_UNSUPPORTED: '此前对话含有暂时无法完整承接的内容,本轮未新建或发送;请联系管理员检查历史内容类型。',
|
|
60
|
-
SYSTEM_PROMPT_UPDATE_UNSUPPORTED: '远端不能更新原会话的系统与开发者要求,本轮未发送;请新建会话。',
|
|
61
50
|
PROMPT_CONTENT_UNSUPPORTED: '远端没有声明这类输入能力,本轮未发送;请使用受支持的内容或联系管理员。',
|
|
62
51
|
ATTACHMENT_REQUIRED: '我需要官方附件组件读取这张图片,请联系管理员检查组件。',
|
|
63
52
|
ATTACHMENT_INVALID: '图片附件没有返回匹配的已核验内容,本轮未发送;请重新添加图片或联系管理员。',
|
|
64
53
|
ACP_MESSAGE_TOO_LARGE: '本轮输入超过会话消息容量,未截断或发送;请联系管理员调整acpMaxMessageBytes。',
|
|
65
|
-
ACP_CLIENT_LOST: '我需要管理员核对并结束遗留的主机会话;当前保留原进程,没有代答旧审批。',
|
|
66
|
-
ONESHOT_CONTEXT_REQUIRED: '首版单次模式不支持图片或系统与开发者上下文,请改用会话模式。',
|
|
67
|
-
MODEL_CONFIGURATION_UNSUPPORTED: '单次模式不支持确认当前模型与推理等级,本轮未发送;请改用会话模式。',
|
|
68
|
-
INPUT_DELIVERY_UNCONFIRMED: '上一轮输入的处理结果尚未确认;没有自动重发,你的原话仍保留,请先核对技术详情。',
|
|
69
|
-
MODEL_SELECTION_REQUIRED: '旧远端恢复记录没有明确模型选择,本轮未发送;请新建会话并选择模型。',
|
|
70
|
-
MODEL_RESOLUTION_UNCONFIRMED: '主机目录尚未给出所选模型的唯一具体型号,本轮未发送;你的原话仍保留,请联系管理员核对模型目录。',
|
|
71
|
-
REMOTE_CLEANUP_UNCONFIRMED: '原主机会话的清理结果尚未确认,已阻断继续发送;请联系管理员核对,不能自动重开。',
|
|
72
54
|
};
|
|
73
55
|
if (messages[code])
|
|
74
56
|
return messages[code];
|
|
75
57
|
if (code === 'EMPLOYEE_OPERATION_UNSUPPORTED')
|
|
76
|
-
return '
|
|
77
|
-
if (code === 'AW_EMPLOYEE_COLD_RESUME_UNSUPPORTED'
|
|
78
|
-
return '
|
|
58
|
+
return '这项操作暂不支持在本机工作区执行;本轮已停止,原记录仍可查看。';
|
|
59
|
+
if (code === 'AW_EMPLOYEE_COLD_RESUME_UNSUPPORTED')
|
|
60
|
+
return '本机执行连接已关闭;恢复连接后可在原会话重新发送,原记录仍可查看。';
|
|
79
61
|
if (code === 'AW_EMPLOYEE_HOST_AUXILIARY_CONFIG_UNSUPPORTED')
|
|
80
|
-
return '
|
|
62
|
+
return '主机上的一项扩展暂不能在你电脑上使用,本轮未执行,请查看技术详情。';
|
|
81
63
|
if (code === 'AW_EMPLOYEE_HOST_PROJECT_CONFIG_UNSUPPORTED')
|
|
82
64
|
return '主机上存在与本机工作区路径重合的项目配置,当前版本无法安全应用,本轮没有执行,请联系管理员。';
|
|
83
|
-
if (code === 'AW_EMPLOYEE_EXECUTOR_MCP_UNSUPPORTED')
|
|
84
|
-
return '本机 HTTP MCP 当前配置策略为拒绝,本轮没有继续执行;管理员可在远程助手参数中调整本机 HTTP MCP 策略,新建会话后生效。';
|
|
85
65
|
if (['AW_EMPLOYEE_CONFIG_ADMISSION_INVALID', 'AW_EMPLOYEE_CONFIG_ADMISSION_FAILED', 'AW_EMPLOYEE_EXECUTOR_CONFIG_PROTOCOL_INVALID', 'AW_EMPLOYEE_EXECUTOR_CONFIG_READ_FAILED'].includes(code))
|
|
86
66
|
return '无法核验这次本机工作区的助手配置,本轮没有继续执行,请联系管理员查看技术详情。';
|
|
87
67
|
if (code === 'AW_EMPLOYEE_MCP_UNSUPPORTED')
|
|
88
|
-
return '
|
|
68
|
+
return '这项扩展暂不能在你电脑上使用,本轮未执行。';
|
|
89
69
|
if (code === 'AW_EMPLOYEE_HOST_AUXILIARY_UNSUPPORTED')
|
|
90
70
|
return '这项辅助操作尚未支持在员工电脑执行,本轮没有执行。';
|
|
91
71
|
if (code === 'AW_EMPLOYEE_SLASH_COMMAND_UNSUPPORTED')
|
|
@@ -96,9 +76,9 @@ export function employeeFailure(code, brand = 'codex') {
|
|
|
96
76
|
return '当前助手的项目配置覆盖与本机执行不兼容,本轮没有执行,请联系管理员。';
|
|
97
77
|
if (code === 'EMPLOYEE_PLATFORM_UNSUPPORTED')
|
|
98
78
|
return brand === 'claude' ? '本机执行目前只支持Mac;当前设备尚不支持,本轮未执行。' : '当前版本的Codex本机执行仅验证了Apple芯片Mac,本轮没有执行。';
|
|
99
|
-
if (code
|
|
100
|
-
return '
|
|
79
|
+
if (code === 'AW_EMPLOYEE_BINARY_MISSING')
|
|
80
|
+
return '本机执行组件没有装齐,本轮没有执行,请重新安装插件。';
|
|
101
81
|
if (code.startsWith('AW_EMPLOYEE_') || code.startsWith('EMPLOYEE_'))
|
|
102
|
-
return '
|
|
103
|
-
return
|
|
82
|
+
return '你电脑上的执行连接已中断,本轮已停止;操作可能已部分执行,请先确认文件,恢复后可在原会话继续。';
|
|
83
|
+
return '本轮没有完成。请检查连接,恢复后可在原会话继续;操作可能已部分执行,请先确认文件。';
|
|
104
84
|
}
|
package/dist/provider.d.ts
CHANGED
|
@@ -3,18 +3,14 @@ import type { AgentApp } from '@agentclientprotocol/sdk';
|
|
|
3
3
|
import type { AgentApp as ExtendedAgentApp } from '@agentclientprotocol/sdk/unstable';
|
|
4
4
|
import type { ConnectState, ConnectNeed, ConnectApi as LConnectApi, ConnectionState, LoginPromptState } from '@ai-workbench/connect/api';
|
|
5
5
|
export type { ConnectionState, LoginPromptState } from '@ai-workbench/connect/api';
|
|
6
|
-
import type { OneShotRuntime } from './job.ts';
|
|
7
6
|
import type { BrokerTransport, BrokerSettings } from './broker.ts';
|
|
8
7
|
import type { Interaction, Invocation } from './interaction.ts';
|
|
9
8
|
import { type AgentDefinition } from './agents.ts';
|
|
10
|
-
import type { NativeWorkspaceApi,
|
|
9
|
+
import type { NativeWorkspaceApi, LoginProvider } from './connect-contract.ts';
|
|
11
10
|
import type { DetailChannel } from './remote-details.ts';
|
|
12
|
-
import type { WorkspaceNoticePresentation } from './workspace-notice.ts';
|
|
13
|
-
import { StageTiming } from './stage-timing.ts';
|
|
14
|
-
import type { RecoveryJournal, AcpRecovery } from './recovery.ts';
|
|
15
11
|
import type { EmployeeProviderOptions } from './employee-provider.ts';
|
|
16
|
-
import
|
|
17
|
-
import type {
|
|
12
|
+
import type { SourceAdmissionStage } from './workspace-source.ts';
|
|
13
|
+
import type { LocalWorkspaceContext } from '@ai-workbench/connect/api';
|
|
18
14
|
import type { EmployeeRouting } from './employee-relay.ts';
|
|
19
15
|
import type { HostWorkspacePresentation } from './input.ts';
|
|
20
16
|
export interface EmployeeExecution {
|
|
@@ -38,7 +34,6 @@ export interface Runtime {
|
|
|
38
34
|
readable: ReadableStream<Uint8Array>;
|
|
39
35
|
} | AgentApp | ExtendedAgentApp;
|
|
40
36
|
broker?: BrokerTransport;
|
|
41
|
-
oneShot?: OneShotRuntime;
|
|
42
37
|
loginRequired?: () => Promise<void>;
|
|
43
38
|
dispose?: (cause?: CloseCause) => Promise<void>;
|
|
44
39
|
binding?: {
|
|
@@ -47,14 +42,8 @@ export interface Runtime {
|
|
|
47
42
|
revision: number;
|
|
48
43
|
};
|
|
49
44
|
connection?: ConnectionState;
|
|
50
|
-
workspaceNotice?: WorkspaceNoticePresentation;
|
|
51
45
|
details?: DetailChannel;
|
|
52
|
-
recoveredSession?: AcpRecovery;
|
|
53
|
-
restartNotice?: string;
|
|
54
46
|
detach?: (cause?: CloseCause) => Promise<void>;
|
|
55
|
-
restartInputIds?: readonly string[];
|
|
56
|
-
freshSessionConfirmed?: boolean;
|
|
57
|
-
saveCheckpoint?: (id: string, acp: AcpRecovery) => Promise<boolean>;
|
|
58
47
|
detailContext?: () => {
|
|
59
48
|
turn: string | number | null;
|
|
60
49
|
step: string | number | null;
|
|
@@ -65,7 +54,6 @@ export interface Runtime {
|
|
|
65
54
|
workspaceId: string;
|
|
66
55
|
cwd: string;
|
|
67
56
|
acpMaxMessageBytes: number;
|
|
68
|
-
httpMcpPolicy?: 'reject' | 'ignore';
|
|
69
57
|
};
|
|
70
58
|
employeeExecution?: (params: unknown, signal?: AbortSignal) => Promise<Record<string, unknown>>;
|
|
71
59
|
employeePresentation?: string;
|
|
@@ -74,29 +62,21 @@ export interface Runtime {
|
|
|
74
62
|
}
|
|
75
63
|
export interface RuntimeRequest extends Invocation {
|
|
76
64
|
closeDiagnostics?: CloseDiagnostics;
|
|
77
|
-
requireFreshSession?: boolean;
|
|
78
65
|
previousContextSha256?: string;
|
|
79
66
|
preflightFailureRecorded?: boolean;
|
|
80
67
|
recordEarlyFailure?: (error: unknown, stage: SourceAdmissionStage) => Promise<void>;
|
|
81
68
|
userInputIds?: readonly string[];
|
|
82
|
-
|
|
69
|
+
localContext?: Readonly<LocalWorkspaceContext>;
|
|
83
70
|
localAdmissionCheck?: () => void;
|
|
84
|
-
readonly localAcceptanceId?: string;
|
|
85
71
|
userMessageIds?: readonly string[];
|
|
86
|
-
recoveryJournal?: RecoveryJournal;
|
|
87
72
|
detailChannel?: DetailChannel;
|
|
88
|
-
validateContext?: (ignoreCancellation?: boolean) => Promise<void>;
|
|
89
|
-
verifyRecovery?: () => Promise<boolean>;
|
|
90
|
-
employeeHttpMcpPolicy?: 'reject' | 'ignore';
|
|
91
73
|
acpMaxMessageBytes?: number;
|
|
92
74
|
employeeScope?: string;
|
|
93
75
|
contextSha256?: string;
|
|
94
76
|
resumeSessionId?: string;
|
|
95
|
-
recoveryCheckpointId?: string;
|
|
96
77
|
bindingRevision?: number;
|
|
97
78
|
currentInputIds?: readonly string[];
|
|
98
|
-
|
|
99
|
-
mode: 'session' | 'one-shot';
|
|
79
|
+
mode?: 'session';
|
|
100
80
|
cwd?: string;
|
|
101
81
|
identity?: string;
|
|
102
82
|
bindingId?: string;
|
|
@@ -150,7 +130,7 @@ type Result<T> = {
|
|
|
150
130
|
} & Partial<Pick<ConnectNeed, 'officialReason' | 'layer' | 'actor' | 'action' | 'lastSeen'>>;
|
|
151
131
|
};
|
|
152
132
|
/** 消费正式connect-api 0.7公开子集;X不响应L登录票据、不直接调用登录。 */
|
|
153
|
-
export interface ConnectApi extends Pick<LConnectApi, 'getConnectionState' | 'getLoginPromptState' | 'requestLoginPrompt' | 'refreshLoginPrompts'>, Partial<NativeWorkspaceApi>, Partial<Pick<LConnectApi, '
|
|
133
|
+
export interface ConnectApi extends Pick<LConnectApi, 'getConnectionState' | 'getLoginPromptState' | 'requestLoginPrompt' | 'refreshLoginPrompts'>, Partial<NativeWorkspaceApi>, Partial<Pick<LConnectApi, 'getModelCatalogTarget' | 'onConnectionState' | 'onLoginPromptState' | 'getWorkspaceLocationState' | 'getLocalWorkspaceContext' | 'onWorkspaceLocationState' | 'selectWorkspaceLocation'>> {
|
|
154
134
|
getState?(): ConnectState;
|
|
155
135
|
getSshTarget(): Promise<Result<ConnectTarget>>;
|
|
156
136
|
checkLogin(provider: LoginProvider): Promise<Result<{
|
|
@@ -161,14 +141,14 @@ export interface ConnectApi extends Pick<LConnectApi, 'getConnectionState' | 'ge
|
|
|
161
141
|
provider: string;
|
|
162
142
|
loggedIn: boolean;
|
|
163
143
|
}>>;
|
|
164
|
-
listProjects(): Promise<Result<{
|
|
144
|
+
listProjects?(): Promise<Result<{
|
|
165
145
|
projects: Project[];
|
|
166
146
|
unavailable: {
|
|
167
147
|
name: string;
|
|
168
148
|
reason: string;
|
|
169
149
|
}[];
|
|
170
150
|
}>>;
|
|
171
|
-
createProject(name: string): Promise<Result<Project>>;
|
|
151
|
+
createProject?(name: string): Promise<Result<Project>>;
|
|
172
152
|
}
|
|
173
153
|
export declare function requireLoginCoordinator(api: ConnectApi): void;
|
|
174
154
|
export declare function requireLoginState(state: LoginPromptState): void;
|
|
@@ -192,10 +172,6 @@ export declare function identity(t: ConnectTarget): string;
|
|
|
192
172
|
export declare function requireNativeWorkspace(api: ConnectApi): asserts api is ConnectApi & NativeWorkspaceApi;
|
|
193
173
|
/** Authorization stays in L; ensureReady only checks and records the need. */
|
|
194
174
|
export declare function offerLogin(connect: ConnectApi, request: Invocation, currentApi?: () => ConnectApi | undefined, agent?: AgentDefinition): Promise<void>;
|
|
195
|
-
export interface NoticeConsumer {
|
|
196
|
-
reconcile(request: RuntimeRequest, api: ConnectApi): Promise<void>;
|
|
197
|
-
deliver(notice: WorkspaceNotice, resolved: SessionProjectTarget, request: RuntimeRequest, api: ConnectApi): Promise<WorkspaceNoticePresentation | void>;
|
|
198
|
-
}
|
|
199
175
|
export type LocalRuntimeProvider = ((request: RuntimeRequest, api: ConnectApi, connection: ConnectionState, target: ConnectTarget) => Promise<Runtime | undefined>) & {
|
|
200
176
|
admit?: (request: RuntimeRequest, api: ConnectApi, connection: ConnectionState, target: ConnectTarget) => Promise<void>;
|
|
201
177
|
};
|
|
@@ -203,8 +179,10 @@ export declare function sameTarget(a: ConnectTarget, b: ConnectTarget): boolean;
|
|
|
203
179
|
export declare function connectProvider(get: () => ConnectApi | undefined, options?: {
|
|
204
180
|
agent?: AgentDefinition;
|
|
205
181
|
ask?: Interaction;
|
|
206
|
-
|
|
207
|
-
|
|
182
|
+
workspace?: (request: RuntimeRequest) => Promise<{
|
|
183
|
+
id: string;
|
|
184
|
+
path: string;
|
|
185
|
+
}>;
|
|
208
186
|
employee?: EmployeeProviderOptions;
|
|
209
187
|
local?: LocalRuntimeProvider;
|
|
210
188
|
details?: (request: RuntimeRequest, api: ConnectApi, connection: ConnectionState, target: ConnectTarget) => Promise<DetailChannel>;
|