dsh-better-copilot 0.1.1 → 0.2.0
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 +13 -0
- package/README.md +19 -0
- package/dist/client.js +98 -0
- package/package.json +14 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.2.0 — read-only subagent route badge
|
|
4
|
+
|
|
5
|
+
- Add a browser client half that shows an addressed subagent's effective model
|
|
6
|
+
and reasoning effort in the Web session header, beside the title. The label is
|
|
7
|
+
text only: no selector, no click target, no Host write, because the child's
|
|
8
|
+
route is fixed at creation and reused on resume.
|
|
9
|
+
- Read the route from the existing `modelSelection` session projection and show
|
|
10
|
+
an adapter-defaulted effort as `default`. Provider/model/effort ids render
|
|
11
|
+
verbatim; catalog display names are not available to client plugins.
|
|
12
|
+
- Keep ordinary conversations and the DSH-rendered subagent catalog untouched.
|
|
13
|
+
Ship the bundle through `./client` and a `dsh.client` declaration, with render
|
|
14
|
+
tests and the publication allowlist updated.
|
|
15
|
+
|
|
3
16
|
## 0.1.1 — DSH 0.2.2-rc.1 compatibility
|
|
4
17
|
|
|
5
18
|
- Retarget the manifest, peer ranges and development pins to DSH `0.2.2-rc.1`
|
package/README.md
CHANGED
|
@@ -101,6 +101,25 @@ tool schemas that lack one for a configured Copilot route and model family, and
|
|
|
101
101
|
leaves every other byte of the request untouched. It never replaces an adapter or
|
|
102
102
|
another plugin's settings, and a guard failure dispatches the original body.
|
|
103
103
|
|
|
104
|
+
## Subagent model badge (Web)
|
|
105
|
+
|
|
106
|
+
The package now carries a small browser client half. When a subagent
|
|
107
|
+
conversation is open in the Web GUI, the session header shows the child's
|
|
108
|
+
effective route as muted text next to the title — for example
|
|
109
|
+
`gpt-6.1-sol · high`. The label is read-only: the plugin renders no selector and
|
|
110
|
+
writes nothing back, because the Host fixes a child's provider, model and
|
|
111
|
+
reasoning effort when the subagent is created and reuses the recorded route on
|
|
112
|
+
resume. An adapter-defaulted effort appears as `default`, and the tooltip and
|
|
113
|
+
accessible name say that the route is fixed.
|
|
114
|
+
|
|
115
|
+
The badge reads the child Session's `modelSelection` projection; it adds no Host
|
|
116
|
+
service, configuration field or RPC. Ids are shown exactly as the Host records
|
|
117
|
+
them, because catalog display names are not exposed to third-party client
|
|
118
|
+
plugins. Ordinary conversations are unchanged, and the subagent catalog
|
|
119
|
+
dropdown is untouched: DSH renders those rows in its own client package rather
|
|
120
|
+
than through an extension slot. The browser half is published as `./client`
|
|
121
|
+
and declared through `dsh.client`; no additional wiring is needed.
|
|
122
|
+
|
|
104
123
|
## Migration from the three predecessor packages
|
|
105
124
|
|
|
106
125
|
| Was | Now |
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/// <reference path="./client.types.d.ts" />
|
|
3
|
+
/* Read-only subagent route badge for the Web conversation header.
|
|
4
|
+
* The Host fixes a subagent's provider, model and reasoning effort when the
|
|
5
|
+
* child is created, so this client half only presents them. It never renders a
|
|
6
|
+
* selection control and writes nothing back to the Session.
|
|
7
|
+
*/
|
|
8
|
+
window.__ModuleLoader__.load({
|
|
9
|
+
id: 'dsh-better-copilot',
|
|
10
|
+
factory(require) {
|
|
11
|
+
const React = require('react');
|
|
12
|
+
const h = React.createElement;
|
|
13
|
+
const NS = 'better-copilot.subagent';
|
|
14
|
+
const SLOT = 'conversation.session.header.actions';
|
|
15
|
+
const ID = 'better-copilot-subagent-model';
|
|
16
|
+
const en = {
|
|
17
|
+
'badge.defaultEffort': 'default',
|
|
18
|
+
'badge.fixed': "Model and effort are fixed for this subagent's lifetime.",
|
|
19
|
+
'badge.aria': 'Subagent model {model} from {provider}, reasoning effort {effort}. {fixed}',
|
|
20
|
+
};
|
|
21
|
+
const zh = {
|
|
22
|
+
'badge.defaultEffort': '默认',
|
|
23
|
+
'badge.fixed': '该子智能体的模型与推理强度在创建时已固定。',
|
|
24
|
+
'badge.aria': '子智能体模型 {model}({provider}),推理强度 {effort}。{fixed}',
|
|
25
|
+
};
|
|
26
|
+
/** Validate one projected selection; anything malformed is not rendered. */
|
|
27
|
+
function readSelection(value) {
|
|
28
|
+
if (typeof value !== 'object' || value === null)
|
|
29
|
+
return null;
|
|
30
|
+
const candidate = value;
|
|
31
|
+
const provider = typeof candidate.provider === 'string' ? candidate.provider : '';
|
|
32
|
+
const model = typeof candidate.model === 'string' ? candidate.model : '';
|
|
33
|
+
if (provider === '' || model === '')
|
|
34
|
+
return null;
|
|
35
|
+
const reasoningEffort = typeof candidate.reasoningEffort === 'string' && candidate.reasoningEffort !== ''
|
|
36
|
+
? candidate.reasoningEffort
|
|
37
|
+
: undefined;
|
|
38
|
+
return reasoningEffort === undefined ? { provider, model } : { provider, model, reasoningEffort };
|
|
39
|
+
}
|
|
40
|
+
/** Read the effective selection from the modelSelection wire view. */
|
|
41
|
+
function selectedOf(view) {
|
|
42
|
+
if (typeof view !== 'object' || view === null)
|
|
43
|
+
return null;
|
|
44
|
+
const projected = view;
|
|
45
|
+
return readSelection(projected.next) ?? readSelection(projected.lastUsed);
|
|
46
|
+
}
|
|
47
|
+
/** Compose the visible label, tooltip and accessible name for one route. */
|
|
48
|
+
function subagentBadge(selection, t) {
|
|
49
|
+
const explicit = selection.reasoningEffort;
|
|
50
|
+
const effort = explicit === undefined ? t('badge.defaultEffort') : explicit;
|
|
51
|
+
const route = explicit === undefined
|
|
52
|
+
? `${selection.provider}/${selection.model}`
|
|
53
|
+
: `${selection.provider}/${selection.model} · ${explicit}`;
|
|
54
|
+
return {
|
|
55
|
+
label: `${selection.model} · ${effort}`,
|
|
56
|
+
title: `${route} — ${t('badge.fixed')}`,
|
|
57
|
+
aria: t('badge.aria', {
|
|
58
|
+
provider: selection.provider,
|
|
59
|
+
model: selection.model,
|
|
60
|
+
effort,
|
|
61
|
+
fixed: t('badge.fixed'),
|
|
62
|
+
}),
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
const badgeStyle = {
|
|
66
|
+
display: 'inline-block',
|
|
67
|
+
maxWidth: '26ch',
|
|
68
|
+
overflow: 'hidden',
|
|
69
|
+
color: 'var(--dsw-alias-label-tertiary)',
|
|
70
|
+
fontSize: '12px',
|
|
71
|
+
lineHeight: '18px',
|
|
72
|
+
whiteSpace: 'nowrap',
|
|
73
|
+
textOverflow: 'ellipsis',
|
|
74
|
+
verticalAlign: 'middle',
|
|
75
|
+
cursor: 'default',
|
|
76
|
+
};
|
|
77
|
+
/** Read-only header cell: visible only for an addressed subagent's own route. */
|
|
78
|
+
function SubagentModelBadge({ sessionId, useSessions, useProjection, t }) {
|
|
79
|
+
const subagent = useSessions((state) => state.byId[sessionId]?.origin === 'subagent');
|
|
80
|
+
const view = useProjection('modelSelection');
|
|
81
|
+
if (!subagent)
|
|
82
|
+
return null;
|
|
83
|
+
const selection = selectedOf(view);
|
|
84
|
+
if (selection === null)
|
|
85
|
+
return null;
|
|
86
|
+
const badge = subagentBadge(selection, t);
|
|
87
|
+
return h('span', { style: badgeStyle, title: badge.title, 'aria-label': badge.aria }, badge.label);
|
|
88
|
+
}
|
|
89
|
+
function apply(ctx) {
|
|
90
|
+
ctx.effect(() => ctx.locale.register(NS, { en, zh }));
|
|
91
|
+
ctx.slots.inject(SLOT, () => ctx.slots.register({ name: SLOT, id: ID, order: 15, locale: NS }, SubagentModelBadge));
|
|
92
|
+
}
|
|
93
|
+
return {
|
|
94
|
+
inject: ['slots', 'locale'],
|
|
95
|
+
apply,
|
|
96
|
+
};
|
|
97
|
+
},
|
|
98
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-better-copilot",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Account-aware GitHub Copilot model discovery, Copilot-compatible wire identity, native Responses web search and a Copilot Gemini tool-declaration guard in one DeepSeek Harness plugin.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
"types": "./dist/guard.d.ts",
|
|
31
31
|
"import": "./dist/guard.js"
|
|
32
32
|
},
|
|
33
|
+
"./client": "./dist/client.js",
|
|
33
34
|
"./package.json": "./package.json"
|
|
34
35
|
},
|
|
35
36
|
"files": [
|
|
@@ -89,18 +90,26 @@
|
|
|
89
90
|
"@deepseek-ai/dsh-system-prompt": "0.2.2-rc.1",
|
|
90
91
|
"@deepseek-ai/dsh-web": "0.2.2-rc.1",
|
|
91
92
|
"@deepseek-ai/schemastery": "3.19.0",
|
|
92
|
-
"@earendil-works/pi-ai": "1.3.0"
|
|
93
|
+
"@earendil-works/pi-ai": "1.3.0",
|
|
94
|
+
"@types/react": "^19.3.0",
|
|
95
|
+
"@types/react-dom": "^19.3.0",
|
|
96
|
+
"react": "^19.3.0",
|
|
97
|
+
"react-dom": "^19.3.0"
|
|
93
98
|
},
|
|
94
99
|
"dsh": {
|
|
95
100
|
"manifestVersion": 1,
|
|
96
101
|
"bundle": {
|
|
97
102
|
"patch": "./cordis.patch.yml"
|
|
103
|
+
},
|
|
104
|
+
"client": {
|
|
105
|
+
"platform": "web",
|
|
106
|
+
"immediately": true
|
|
98
107
|
}
|
|
99
108
|
},
|
|
100
109
|
"scripts": {
|
|
101
|
-
"build": "tsc -p tsconfig.json",
|
|
102
|
-
"typecheck": "tsc -p tsconfig.json --noEmit && tsc -p test/tsconfig.json",
|
|
103
|
-
"test": "pnpm run build && node --import tsx --test test/catalog.test.ts test/discovery.test.ts test/identity.test.ts test/secrets.test.ts test/catalog-plugin.test.ts test/config.test.ts test/composition.test.ts test/auth.test.ts test/refresh.test.ts test/provider.test.ts test/responses.test.ts test/search-plugin.test.ts test/schema.test.ts test/guard.test.ts test/guard-plugin.test.ts test/patch.test.ts",
|
|
110
|
+
"build": "tsc -p tsconfig.json && tsc -p tsconfig.client.json",
|
|
111
|
+
"typecheck": "tsc -p tsconfig.json --noEmit && tsc -p test/tsconfig.json && tsc -p tsconfig.client.json --noEmit",
|
|
112
|
+
"test": "pnpm run build && node --import tsx --test test/catalog.test.ts test/discovery.test.ts test/identity.test.ts test/secrets.test.ts test/catalog-plugin.test.ts test/config.test.ts test/composition.test.ts test/auth.test.ts test/refresh.test.ts test/provider.test.ts test/responses.test.ts test/search-plugin.test.ts test/schema.test.ts test/guard.test.ts test/guard-plugin.test.ts test/patch.test.ts test/client.render.test.ts",
|
|
104
113
|
"test:integration": "pnpm run build && node --import tsx --test test/integration/nested-layout.test.ts test/integration/catalog-runtime.test.ts test/integration/enterprise.test.ts test/integration/identity-wire.test.ts test/integration/search-runtime.test.ts test/integration/guard-runtime.test.ts test/integration/wire.test.ts",
|
|
105
114
|
"test:types": "pnpm run build && tsc -p test/types/tsconfig.json",
|
|
106
115
|
"test:pack": "pnpm run build && tsx ../../scripts/check-pack.ts .",
|