@khorsheed/dsh-local-agent-codex 0.1.0-rc.8 → 0.2.0-rc.3
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 +15 -0
- package/README.en.md +34 -20
- package/README.i18n.yaml +2 -2
- package/README.md +34 -20
- package/cordis.patch.yml +16 -24
- package/lib/client.js +816 -322
- package/lib/index.js +501 -104
- package/lib/tool.js +40 -0
- package/lib/types/client/SettingsCard.d.ts +73 -24
- package/lib/types/client/SettingsCard.js +110 -140
- package/lib/types/client/index.d.ts +6 -26
- package/lib/types/client/index.js +136 -50
- package/lib/types/client/locales.d.ts +34 -24
- package/lib/types/client/locales.js +38 -28
- package/lib/types/codex-cli-provider.d.ts +21 -4
- package/lib/types/codex-cli-provider.js +60 -27
- package/lib/types/endpoint-auth.d.ts +194 -0
- package/lib/types/endpoint-auth.js +300 -0
- package/lib/types/index.d.ts +19 -3
- package/lib/types/index.js +127 -28
- package/lib/types/live-driver.d.ts +9 -0
- package/lib/types/live-driver.js +16 -2
- package/lib/types/live-switch.d.ts +7 -0
- package/lib/types/live-switch.js +1 -0
- package/lib/types/model-broker.d.ts +12 -2
- package/lib/types/model-broker.js +9 -5
- package/lib/types/model-catalog.d.ts +53 -9
- package/lib/types/model-catalog.js +95 -12
- package/lib/types/provision.d.ts +12 -27
- package/lib/types/provision.js +19 -40
- package/lib/types/records.d.ts +0 -7
- package/lib/types/records.js +1 -19
- package/lib/types/tool.d.ts +54 -0
- package/lib/types/tool.js +34 -0
- package/locale/en.json +2 -2
- package/locale/zh.json +2 -2
- package/package.json +25 -23
- package/lib/invariant.js +0 -31
- package/lib/types/invariant.d.ts +0 -16
- package/lib/types/invariant.js +0 -33
|
@@ -1,30 +1,51 @@
|
|
|
1
1
|
import { bindSettingsScope } from '@khorsheed/dsh-local-agent/src/client/settings-scope.ts';
|
|
2
|
-
import { en, NS, zh } from './locales.js';
|
|
3
|
-
import { CodexBundleConfig, CodexSettingsCard, } from './SettingsCard.js';
|
|
4
|
-
export { CodexBundleConfig, CodexSettingsCard } from './SettingsCard.js';
|
|
5
|
-
export { en, NS, zh };
|
|
6
2
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
3
|
+
* Local-agent-codex plugin, browser half: the codex settings card — a section
|
|
4
|
+
* of the family core's「本机 Agent 委派」family card on the Plugins page
|
|
5
|
+
* (registered through the core's `localAgentUi.registerHarnessCard` while the
|
|
6
|
+
* Host serves the `local-agent-codex` namespace), or this package's own
|
|
7
|
+
* `plugins.item` entry when the core predates the family card (the
|
|
8
|
+
* declare-and-degrade fallback). Every install shape serves the row's
|
|
9
|
+
* volatile Config under the row id —
|
|
10
|
+
* standalone install, family bundle, or mode pack — so the card follows the
|
|
11
|
+
* served namespace rather than any carrier bundle, and a composition without
|
|
12
|
+
* the row shows no trace of it. The card carries the family core's shared
|
|
13
|
+
* ProviderAuthBlock (login/logout/device-code, backed by the core's
|
|
14
|
+
* localAgentGateway Remote and the commands channel — endpoint-key only, no
|
|
15
|
+
* login flow), the endpoint credential form, the family core's shared
|
|
16
|
+
* ModelListSection (the curated ordered shortlist — first entry is the
|
|
17
|
+
* default model — edited through the gateway's modelList/configureModelList
|
|
18
|
+
* Remotes, the add dialog fed by modelDirectory), and the resident-mode
|
|
19
|
+
* block (live switch), whose writes ride
|
|
20
|
+
* the bound settingsScope — the host watcher hot-applies them, no reload.
|
|
21
|
+
* Every read degrades: an absent gateway renders the auth block's
|
|
22
|
+
* 'unavailable' state and drops the model surfaces, an
|
|
23
|
+
* unregistered namespace disables the live controls.
|
|
24
|
+
* @module @khorsheed/dsh-local-agent-codex/client
|
|
10
25
|
*/
|
|
11
|
-
|
|
26
|
+
import { createElement, useSyncExternalStore } from 'react';
|
|
27
|
+
import { en, NS, zh } from './locales.js';
|
|
28
|
+
import { CodexBundleConfig, CodexCardSection, } from './SettingsCard.js';
|
|
29
|
+
export { CodexBundleConfig, CodexCardSection, CodexSettingsCard } from './SettingsCard.js';
|
|
30
|
+
export { en, NS, zh };
|
|
12
31
|
/**
|
|
13
32
|
* Required services: slot registry, command Remote, and locale registry. The
|
|
14
33
|
* settings scope is NOT a static inject — its service name differs per host
|
|
15
34
|
* line (`settingsScope` on 0.1.5, `configForms` on rc.1), so a static entry
|
|
16
35
|
* would pend the whole client plugin on the other line; bindSettingsScope
|
|
17
36
|
* probes the serving one instead (the settings client package is a declared
|
|
18
|
-
* client inject, so one of them is always already up).
|
|
37
|
+
* client inject, so one of them is always already up). The card track probes
|
|
38
|
+
* `configForms` through the same kind of deferred inject (see apply).
|
|
19
39
|
*/
|
|
20
40
|
export const inject = ['slots', 'remote', 'remote.commands', 'locale'];
|
|
21
41
|
/**
|
|
22
|
-
* Client plugin body: register the dictionaries and the codex settings
|
|
23
|
-
*
|
|
42
|
+
* Client plugin body: register the dictionaries and the codex settings card
|
|
43
|
+
* bound to the local-agent-codex namespace.
|
|
24
44
|
* @param ctx - client root context.
|
|
25
45
|
*/
|
|
26
46
|
export function apply(ctx) {
|
|
27
47
|
ctx.effect(() => ctx.locale.register(NS, { zh, en }), 'local-agent-codex: dictionaries');
|
|
48
|
+
const t = ctx.locale.bind(NS);
|
|
28
49
|
const scope = bindSettingsScope(ctx, 'local-agent-codex');
|
|
29
50
|
// The auth block's copy lives in the family core's dictionary; binding is
|
|
30
51
|
// stable per namespace and late dictionary registration still resolves.
|
|
@@ -34,16 +55,59 @@ export function apply(ctx) {
|
|
|
34
55
|
// never matters, and degrade to the auth block's 'unavailable' state when
|
|
35
56
|
// the core client is absent.
|
|
36
57
|
const gateway = () => ctx.get('remote.localAgentGateway');
|
|
37
|
-
//
|
|
38
|
-
|
|
58
|
+
// The card's inject face minus the hooks compartment — the family-card
|
|
59
|
+
// section consumes this verbatim; the standalone card's slot registration
|
|
60
|
+
// adds the hooks compartment back below.
|
|
61
|
+
const cardFace = () => ({
|
|
39
62
|
scope,
|
|
40
|
-
hooks: { settings: scope },
|
|
41
63
|
authT,
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
64
|
+
// The curated model list's read/write faces, over the same Remotes.
|
|
65
|
+
modelList: {
|
|
66
|
+
read: () => {
|
|
67
|
+
const gw = gateway();
|
|
68
|
+
if (gw === undefined || typeof gw.modelList !== 'function')
|
|
69
|
+
return Promise.resolve(undefined);
|
|
70
|
+
return gw.modelList('codex').then(result => (result.ok ? result.value : undefined));
|
|
71
|
+
},
|
|
72
|
+
write: (models) => {
|
|
73
|
+
const gw = gateway();
|
|
74
|
+
if (gw === undefined || typeof gw.configureModelList !== 'function')
|
|
75
|
+
return Promise.resolve(undefined);
|
|
76
|
+
return gw.configureModelList('codex', models).then(result => (result.ok ? result.value : undefined));
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
// The endpoint's served catalog for the add dialog. A core predating
|
|
80
|
+
// modelDirectory leaves the dialog with its reason.
|
|
81
|
+
modelDirectory: (refresh) => {
|
|
82
|
+
const gw = gateway();
|
|
83
|
+
if (gw === undefined || typeof gw.modelDirectory !== 'function')
|
|
84
|
+
return Promise.resolve(undefined);
|
|
85
|
+
return gw.modelDirectory('codex', undefined, refresh ?? false).then(result => (result.ok ? result.value : undefined));
|
|
86
|
+
},
|
|
87
|
+
// The verify button's probe, over the session-less gateway Remote. A core
|
|
88
|
+
// predating `checkEndpoint` hides the button (declare-and-degrade).
|
|
89
|
+
checkEndpoint: () => {
|
|
90
|
+
const gw = gateway();
|
|
91
|
+
if (gw === undefined || typeof gw.checkEndpoint !== 'function')
|
|
92
|
+
return Promise.resolve(undefined);
|
|
93
|
+
return gw.checkEndpoint('codex').then(result => (result.ok ? result.value : undefined));
|
|
94
|
+
},
|
|
95
|
+
// The credential form's read/write face, over the same session-less
|
|
96
|
+
// Remotes. Absent on a core that predates them — the card hides the form.
|
|
97
|
+
endpointAuth: {
|
|
98
|
+
read: () => {
|
|
99
|
+
const gw = gateway();
|
|
100
|
+
if (gw === undefined || typeof gw.endpointAuth !== 'function')
|
|
101
|
+
return Promise.resolve(undefined);
|
|
102
|
+
return gw.endpointAuth('codex').then(result => (result.ok ? result.value : undefined));
|
|
103
|
+
},
|
|
104
|
+
write: (fields) => {
|
|
105
|
+
const gw = gateway();
|
|
106
|
+
if (gw === undefined || typeof gw.configureEndpoint !== 'function')
|
|
107
|
+
return Promise.resolve(undefined);
|
|
108
|
+
return gw.configureEndpoint('codex', fields).then(result => (result.ok ? result.value : undefined));
|
|
109
|
+
},
|
|
110
|
+
},
|
|
47
111
|
auth: {
|
|
48
112
|
status: name =>
|
|
49
113
|
// The Remote declares (name, scope?) and the client enforces exact arity:
|
|
@@ -54,35 +118,57 @@ export function apply(ctx) {
|
|
|
54
118
|
.then(result => (result.ok ? result.value?.result.text : undefined)),
|
|
55
119
|
},
|
|
56
120
|
});
|
|
57
|
-
// The settings
|
|
58
|
-
|
|
59
|
-
//
|
|
60
|
-
//
|
|
61
|
-
//
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
//
|
|
66
|
-
//
|
|
67
|
-
//
|
|
68
|
-
// the
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
121
|
+
// The settings card injects this face.
|
|
122
|
+
const cardInject = () => ({ ...cardFace(), hooks: { settings: scope } });
|
|
123
|
+
// The family-card section render bypasses the slot renderer's inject.hooks
|
|
124
|
+
// materialization, so bind the scope's selector hook here with the same
|
|
125
|
+
// semantics (a uSES subscription over the scope's own subscribe/getSnapshot).
|
|
126
|
+
const subscribeScope = (listener) => scope.subscribe(listener);
|
|
127
|
+
const readScope = () => scope.getSnapshot();
|
|
128
|
+
const useSettings = (select) => select(useSyncExternalStore(subscribeScope, readScope));
|
|
129
|
+
// One Plugins-page seat gated on the SERVED NAMESPACE, never on the install
|
|
130
|
+
// shape: whichever composition carries the `local-agent-codex` row —
|
|
131
|
+
// standalone install, family bundle, or mode pack — serves the row's
|
|
132
|
+
// volatile Config under the row id, and `whileServed` keeps the
|
|
133
|
+
// registration alive for exactly that span (the official companion
|
|
134
|
+
// convention), so a composition without the row shows no trace of the card.
|
|
135
|
+
// This replaces the retired per-shape seats: `plugins.row.config` hardcoded
|
|
136
|
+
// one carrier bundle into its key, and the host deleted
|
|
137
|
+
// `settings.plugin.item`. The probe rides a deferred inject because
|
|
138
|
+
// configForms exists only on the alpha.2+ host line; a 0.1.5 host never
|
|
139
|
+
// fires it, and a configForms predating whileServed (0.1.6-alpha.2) skips
|
|
140
|
+
// the card.
|
|
141
|
+
ctx.inject(['configForms'], (formsCtx) => {
|
|
142
|
+
const forms = formsCtx.configForms;
|
|
143
|
+
if (typeof forms.whileServed !== 'function')
|
|
144
|
+
return;
|
|
145
|
+
return forms.whileServed(['local-agent-codex'], () => {
|
|
146
|
+
// The family card owns the Plugins-page seat when the core's client
|
|
147
|
+
// provides it: a core new enough answers registerHarnessCard, and this
|
|
148
|
+
// package renders as a section of the「本机 Agent 委派」card instead of
|
|
149
|
+
// its own entry. The probe runs at serve time — a host round-trip past
|
|
150
|
+
// client plugin boot — so a composed core has already provided the
|
|
151
|
+
// service; an old or absent core keeps the standalone card below.
|
|
152
|
+
const ui = ctx.get('localAgentUi');
|
|
153
|
+
if (typeof ui?.registerHarnessCard === 'function') {
|
|
154
|
+
return ui.registerHarnessCard({
|
|
155
|
+
name: 'codex',
|
|
156
|
+
// The retired standalone card's order, kept as the section order.
|
|
157
|
+
order: 120,
|
|
158
|
+
locale: NS,
|
|
159
|
+
label: () => t('card.title'),
|
|
160
|
+
render: ({ active, useSessions }) => createElement(CodexCardSection, { active, useSessions, ...cardFace(), useSettings, t }),
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
return ctx.slots.inject('plugins.item', () => ctx.slots.register({
|
|
164
|
+
name: 'plugins.item',
|
|
165
|
+
id: 'local-agent-codex',
|
|
166
|
+
// Community cards sort after the official settings pages (orders 10-40).
|
|
167
|
+
order: 120,
|
|
168
|
+
label: () => t('card.title'),
|
|
169
|
+
locale: NS,
|
|
170
|
+
inject: cardInject,
|
|
171
|
+
}, CodexBundleConfig));
|
|
172
|
+
});
|
|
173
|
+
});
|
|
88
174
|
}
|
|
@@ -8,18 +8,23 @@ export declare const zh: {
|
|
|
8
8
|
'card.expand': string;
|
|
9
9
|
'card.collapse': string;
|
|
10
10
|
'auth.title': string;
|
|
11
|
-
'
|
|
12
|
-
'
|
|
13
|
-
'
|
|
14
|
-
'
|
|
15
|
-
'
|
|
16
|
-
'
|
|
17
|
-
'
|
|
18
|
-
'
|
|
19
|
-
'
|
|
20
|
-
'
|
|
21
|
-
'
|
|
22
|
-
'
|
|
11
|
+
'endpoint.info.aria': string;
|
|
12
|
+
'endpoint.info': string;
|
|
13
|
+
'endpoint.baseUrl': string;
|
|
14
|
+
'endpoint.baseUrl.placeholder': string;
|
|
15
|
+
'endpoint.apiKey': string;
|
|
16
|
+
'endpoint.secret.configured': string;
|
|
17
|
+
'endpoint.secret.placeholder': string;
|
|
18
|
+
'endpoint.configured': string;
|
|
19
|
+
'endpoint.save': string;
|
|
20
|
+
'endpoint.applied': string;
|
|
21
|
+
'endpoint.error': string;
|
|
22
|
+
'endpoint.check': string;
|
|
23
|
+
'endpoint.checking': string;
|
|
24
|
+
'endpoint.checkDirtyHint': string;
|
|
25
|
+
'endpoint.checkUnavailable': string;
|
|
26
|
+
'endpoint.unavailable': string;
|
|
27
|
+
'endpoint.checkFailed': string;
|
|
23
28
|
'live.title': string;
|
|
24
29
|
'live.info.aria': string;
|
|
25
30
|
'live.info': string;
|
|
@@ -42,18 +47,23 @@ export declare const en: {
|
|
|
42
47
|
'card.expand': string;
|
|
43
48
|
'card.collapse': string;
|
|
44
49
|
'auth.title': string;
|
|
45
|
-
'
|
|
46
|
-
'
|
|
47
|
-
'
|
|
48
|
-
'
|
|
49
|
-
'
|
|
50
|
-
'
|
|
51
|
-
'
|
|
52
|
-
'
|
|
53
|
-
'
|
|
54
|
-
'
|
|
55
|
-
'
|
|
56
|
-
'
|
|
50
|
+
'endpoint.info.aria': string;
|
|
51
|
+
'endpoint.info': string;
|
|
52
|
+
'endpoint.baseUrl': string;
|
|
53
|
+
'endpoint.baseUrl.placeholder': string;
|
|
54
|
+
'endpoint.apiKey': string;
|
|
55
|
+
'endpoint.secret.configured': string;
|
|
56
|
+
'endpoint.secret.placeholder': string;
|
|
57
|
+
'endpoint.configured': string;
|
|
58
|
+
'endpoint.save': string;
|
|
59
|
+
'endpoint.applied': string;
|
|
60
|
+
'endpoint.error': string;
|
|
61
|
+
'endpoint.check': string;
|
|
62
|
+
'endpoint.checking': string;
|
|
63
|
+
'endpoint.checkDirtyHint': string;
|
|
64
|
+
'endpoint.checkUnavailable': string;
|
|
65
|
+
'endpoint.unavailable': string;
|
|
66
|
+
'endpoint.checkFailed': string;
|
|
57
67
|
'live.title': string;
|
|
58
68
|
'live.info.aria': string;
|
|
59
69
|
'live.info': string;
|
|
@@ -3,23 +3,28 @@
|
|
|
3
3
|
export const NS = 'local-agent-codex';
|
|
4
4
|
/** Simplified Chinese dictionary (the key-set source of truth). */
|
|
5
5
|
export const zh = {
|
|
6
|
-
'card.title': '
|
|
7
|
-
'card.description': 'Codex
|
|
6
|
+
'card.title': '本机 Codex 委派',
|
|
7
|
+
'card.description': 'Codex 委派:端点凭据与常驻模式(live)',
|
|
8
8
|
'card.expand': '展开',
|
|
9
9
|
'card.collapse': '收起',
|
|
10
10
|
'auth.title': '认证',
|
|
11
|
-
'
|
|
12
|
-
'
|
|
13
|
-
'
|
|
14
|
-
'
|
|
15
|
-
'
|
|
16
|
-
'
|
|
17
|
-
'
|
|
18
|
-
'
|
|
19
|
-
'
|
|
20
|
-
'
|
|
21
|
-
'
|
|
22
|
-
'
|
|
11
|
+
'endpoint.info.aria': '端点凭据说明',
|
|
12
|
+
'endpoint.info': '这里保存的就是默认 scope 的 endpoint-auth.json(0600,只存本机),它优先于 profile 的 YAML 配置行;宿主 shell 的环境变量从不被读取。配置 API Key 后每轮委派以自定义 provider(wire_api=responses)路由到端点;端点地址留空 = OpenAI 官方端点。密钥绝不写进 profile 文件,也不进入评测条件指纹。没有网页登录:容器轮与宿主轮用同一套凭据,容器里不需要再授权一次。保存对下一轮委派生效,进行中的轮次不受影响。',
|
|
13
|
+
'endpoint.baseUrl': '端点地址(baseUrl)',
|
|
14
|
+
'endpoint.baseUrl.placeholder': '留空 = OpenAI 官方端点',
|
|
15
|
+
'endpoint.apiKey': 'API Key',
|
|
16
|
+
'endpoint.secret.configured': '已配置 · 输入新值更换,留空保存 = 清除',
|
|
17
|
+
'endpoint.secret.placeholder': '未配置',
|
|
18
|
+
'endpoint.configured': '已配置',
|
|
19
|
+
'endpoint.save': '保存凭据',
|
|
20
|
+
'endpoint.applied': '已保存,下一轮委派生效;进行中的轮次不受影响',
|
|
21
|
+
'endpoint.error': '保存失败,请重试',
|
|
22
|
+
'endpoint.check': '验证端点并获取模型',
|
|
23
|
+
'endpoint.checking': '验证中…',
|
|
24
|
+
'endpoint.checkDirtyHint': '有未保存的修改,先保存凭据再验证',
|
|
25
|
+
'endpoint.checkUnavailable': '当前核心不支持端点验证(请升级 local-agent 核心包)',
|
|
26
|
+
'endpoint.unavailable': '当前核心不支持凭据配置(请升级 local-agent 核心包)',
|
|
27
|
+
'endpoint.checkFailed': '验证失败,请重试',
|
|
23
28
|
'live.title': '常驻模式(live)',
|
|
24
29
|
'live.info.aria': '常驻模式说明',
|
|
25
30
|
'live.info': '常驻模式 = 成员进程常驻:输出实时流入成员会话、取消不杀进程、崩溃后自动续上原会话;关闭则每轮独立进程,跑完一次性出结果。设置为全局偏好,对所有后续委派生效。',
|
|
@@ -29,23 +34,28 @@ export const zh = {
|
|
|
29
34
|
};
|
|
30
35
|
/** English dictionary, checked complete against the zh key set. */
|
|
31
36
|
export const en = {
|
|
32
|
-
'card.title': 'Local
|
|
33
|
-
'card.description': 'Codex delegation:
|
|
37
|
+
'card.title': 'Local Codex Delegation',
|
|
38
|
+
'card.description': 'Codex delegation: endpoint credential and resident (live) mode',
|
|
34
39
|
'card.expand': 'Expand',
|
|
35
40
|
'card.collapse': 'Collapse',
|
|
36
41
|
'auth.title': 'Authentication',
|
|
37
|
-
'
|
|
38
|
-
'
|
|
39
|
-
'
|
|
40
|
-
'
|
|
41
|
-
'
|
|
42
|
-
'
|
|
43
|
-
'
|
|
44
|
-
'
|
|
45
|
-
'
|
|
46
|
-
'
|
|
47
|
-
'
|
|
48
|
-
'
|
|
42
|
+
'endpoint.info.aria': 'About the endpoint credential',
|
|
43
|
+
'endpoint.info': "What you save here is the default scope's endpoint-auth.json (mode 0600, local only), which outranks the profile's YAML row; the host shell's environment is never read. With an API Key configured, every delegation round routes at the endpoint through a custom provider (wire_api=responses); a blank endpoint means OpenAI's own. Keys never enter the profile document or an evaluation's condition fingerprint. There is no web login: container rounds share the host's credential and nothing is authorized inside a container. Saving applies to the next delegation round; rounds in flight are unaffected.",
|
|
44
|
+
'endpoint.baseUrl': 'Endpoint (baseUrl)',
|
|
45
|
+
'endpoint.baseUrl.placeholder': "Blank = OpenAI's own endpoint",
|
|
46
|
+
'endpoint.apiKey': 'API Key',
|
|
47
|
+
'endpoint.secret.configured': 'Configured · type to replace, save blank to clear',
|
|
48
|
+
'endpoint.secret.placeholder': 'Not configured',
|
|
49
|
+
'endpoint.configured': 'Configured',
|
|
50
|
+
'endpoint.save': 'Save credential',
|
|
51
|
+
'endpoint.applied': 'Saved — takes effect on the next delegation round; rounds in flight are unaffected',
|
|
52
|
+
'endpoint.error': 'Save failed, please retry',
|
|
53
|
+
'endpoint.check': 'Verify endpoint & list models',
|
|
54
|
+
'endpoint.checking': 'Verifying…',
|
|
55
|
+
'endpoint.checkDirtyHint': 'Unsaved changes — save the credential before verifying',
|
|
56
|
+
'endpoint.checkUnavailable': 'This core cannot verify endpoints (upgrade the local-agent core package)',
|
|
57
|
+
'endpoint.unavailable': 'This core cannot configure credentials (upgrade the local-agent core package)',
|
|
58
|
+
'endpoint.checkFailed': 'Verification failed, please retry',
|
|
49
59
|
'live.title': 'Resident mode (live)',
|
|
50
60
|
'live.info.aria': 'About resident mode',
|
|
51
61
|
'live.info': 'Resident mode keeps the member process alive: output streams into the member session in real time, cancelling does not kill the process, and a crash resumes the same session. Off means every round runs as an independent one-shot process. The setting is global and applies to every later delegation.',
|
|
@@ -20,6 +20,7 @@ import type { Session } from '@deepseek-ai/dsh-session';
|
|
|
20
20
|
import type { SubprocessHandle, SubprocessSpawnSpec } from '@deepseek-ai/dsh-subprocess';
|
|
21
21
|
import type { DelegationExecTarget, LocalAgentToolCalls } from '@khorsheed/dsh-local-agent/types';
|
|
22
22
|
import type { CodexLiveDriver } from './live-driver.ts';
|
|
23
|
+
import { type CodexEndpointAuth } from './endpoint-auth.ts';
|
|
23
24
|
/** Default POSIX grace between subprocess termination tiers. */
|
|
24
25
|
export declare const DEFAULT_DISPOSE_GRACE_MS = 3000;
|
|
25
26
|
/**
|
|
@@ -71,6 +72,7 @@ export declare class CodexCliProvider implements SubagentProvider {
|
|
|
71
72
|
private readonly live?;
|
|
72
73
|
private readonly model?;
|
|
73
74
|
private readonly overrides?;
|
|
75
|
+
private readonly endpoint?;
|
|
74
76
|
readonly name = "codex-local";
|
|
75
77
|
readonly capabilities: SubagentCapabilities;
|
|
76
78
|
readonly inheritsParentContext = false;
|
|
@@ -81,17 +83,25 @@ export declare class CodexCliProvider implements SubagentProvider {
|
|
|
81
83
|
* while a retiring generation still hosts it).
|
|
82
84
|
* @param model - resolver for the configured model, read PER ROUND so a
|
|
83
85
|
* settings-card write takes effect on the next delegation without a
|
|
84
|
-
* reload
|
|
85
|
-
*
|
|
86
|
-
*
|
|
86
|
+
* reload; it receives the round's scope (a named scope's curated list
|
|
87
|
+
* answers first). Undefined (the resolver absent, or returning
|
|
88
|
+
* undefined) leaves the argv exactly as it was before the key existed —
|
|
89
|
+
* the scoped config.toml's own `model` then decides, as it always did.
|
|
87
90
|
* @param overrides - resolver for the member's session-level model override
|
|
88
91
|
* (the composer picker, owned by the model broker). It outranks BOTH the
|
|
89
92
|
* delegation's recorded model and the configured one: on the exec path it
|
|
90
93
|
* re-points the next round's `-m`, and on the live path it is the member's
|
|
91
94
|
* start model — a resident runtime bound to a different model is retired
|
|
92
95
|
* so the round respawns onto the override.
|
|
96
|
+
* @param endpoint - resolver for the scope's endpoint credential, read PER
|
|
97
|
+
* ROUND so a settings-card write takes effect on the next delegation
|
|
98
|
+
* without a reload. A resolution carrying a key routes the round at the
|
|
99
|
+
* relay (a custom `model_providers` entry on the argv, the key in the
|
|
100
|
+
* env); with no key the spawn carries no credential at all.
|
|
93
101
|
*/
|
|
94
|
-
constructor(ctx: Context, sandbox?: CodexSandbox, live?: CodexLiveDriver | ((childSessionId: string) => CodexLiveDriver | undefined) | undefined, model?: (() => string | undefined) | undefined, overrides?: ((childSessionId: string) => string | undefined) | undefined);
|
|
102
|
+
constructor(ctx: Context, sandbox?: CodexSandbox, live?: CodexLiveDriver | ((childSessionId: string) => CodexLiveDriver | undefined) | undefined, model?: ((scope?: string) => string | undefined) | undefined, overrides?: ((childSessionId: string) => string | undefined) | undefined, endpoint?: ((scopeHome: string) => Promise<CodexEndpointAuth>) | undefined);
|
|
103
|
+
/** The scope's endpoint credential for this round; absent resolver = never. */
|
|
104
|
+
private resolveEndpoint;
|
|
95
105
|
/** Resolve the live driver for one round's member, if live is on for it. */
|
|
96
106
|
private liveDriver;
|
|
97
107
|
/** Per-round member-channel registration for the exec path (see {@link registerCodexMemberRun}). */
|
|
@@ -116,6 +126,13 @@ export interface CodexCliRunSpec {
|
|
|
116
126
|
readonly exec?: DelegationExecTarget | undefined;
|
|
117
127
|
/** Resolved endpoint label for diagnostics; absent means the CLI default. */
|
|
118
128
|
readonly endpointLabel?: string | undefined;
|
|
129
|
+
/**
|
|
130
|
+
* The endpoint credential's `-c` config overrides (a custom
|
|
131
|
+
* `model_providers` entry plus the provider selection), spliced next to
|
|
132
|
+
* the member override. Empty when the round carries no endpoint
|
|
133
|
+
* credential — the argv is then byte-identical to the pre-endpoint shape.
|
|
134
|
+
*/
|
|
135
|
+
readonly endpointArgv?: readonly string[] | undefined;
|
|
119
136
|
/** Sandbox policy passed to `codex exec --sandbox`. */
|
|
120
137
|
readonly sandbox: CodexSandbox;
|
|
121
138
|
/**
|