@sagmans/dsh-tui 0.1.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/LICENSE +21 -0
- package/README.md +266 -0
- package/cordis.patch.yml +123 -0
- package/lib/agent/fork.d.ts +24 -0
- package/lib/agent/fork.d.ts.map +1 -0
- package/lib/agent/fork.js +25 -0
- package/lib/agent/fork.js.map +1 -0
- package/lib/agent/history.d.ts +78 -0
- package/lib/agent/history.d.ts.map +1 -0
- package/lib/agent/history.js +179 -0
- package/lib/agent/history.js.map +1 -0
- package/lib/agent/host.d.ts +58 -0
- package/lib/agent/host.d.ts.map +1 -0
- package/lib/agent/host.js +59 -0
- package/lib/agent/host.js.map +1 -0
- package/lib/agent/model.d.ts +61 -0
- package/lib/agent/model.d.ts.map +1 -0
- package/lib/agent/model.js +92 -0
- package/lib/agent/model.js.map +1 -0
- package/lib/agent/present.d.ts +12 -0
- package/lib/agent/present.d.ts.map +1 -0
- package/lib/agent/present.js +52 -0
- package/lib/agent/present.js.map +1 -0
- package/lib/agent/presets.d.ts +75 -0
- package/lib/agent/presets.d.ts.map +1 -0
- package/lib/agent/presets.js +117 -0
- package/lib/agent/presets.js.map +1 -0
- package/lib/agent/projections.d.ts +16 -0
- package/lib/agent/projections.d.ts.map +1 -0
- package/lib/agent/projections.js +31 -0
- package/lib/agent/projections.js.map +1 -0
- package/lib/agent/status.d.ts +46 -0
- package/lib/agent/status.d.ts.map +1 -0
- package/lib/agent/status.js +67 -0
- package/lib/agent/status.js.map +1 -0
- package/lib/cards.d.ts +88 -0
- package/lib/cards.d.ts.map +1 -0
- package/lib/cards.js +218 -0
- package/lib/cards.js.map +1 -0
- package/lib/compat/probe.d.ts +33 -0
- package/lib/compat/probe.d.ts.map +1 -0
- package/lib/compat/probe.js +74 -0
- package/lib/compat/probe.js.map +1 -0
- package/lib/config.d.ts +13 -0
- package/lib/config.d.ts.map +1 -0
- package/lib/config.js +49 -0
- package/lib/config.js.map +1 -0
- package/lib/contracts.d.ts +32 -0
- package/lib/contracts.d.ts.map +1 -0
- package/lib/contracts.js +2 -0
- package/lib/contracts.js.map +1 -0
- package/lib/export.d.ts +15 -0
- package/lib/export.d.ts.map +1 -0
- package/lib/export.js +52 -0
- package/lib/export.js.map +1 -0
- package/lib/gates.d.ts +85 -0
- package/lib/gates.d.ts.map +1 -0
- package/lib/gates.js +216 -0
- package/lib/gates.js.map +1 -0
- package/lib/identity.d.ts +33 -0
- package/lib/identity.d.ts.map +1 -0
- package/lib/identity.js +49 -0
- package/lib/identity.js.map +1 -0
- package/lib/index.d.ts +24 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +1196 -0
- package/lib/index.js.map +1 -0
- package/lib/input/completion.d.ts +22 -0
- package/lib/input/completion.d.ts.map +1 -0
- package/lib/input/completion.js +27 -0
- package/lib/input/completion.js.map +1 -0
- package/lib/input/submission.d.ts +62 -0
- package/lib/input/submission.d.ts.map +1 -0
- package/lib/input/submission.js +80 -0
- package/lib/input/submission.js.map +1 -0
- package/lib/jobs.d.ts +64 -0
- package/lib/jobs.d.ts.map +1 -0
- package/lib/jobs.js +123 -0
- package/lib/jobs.js.map +1 -0
- package/lib/startup.d.ts +17 -0
- package/lib/startup.d.ts.map +1 -0
- package/lib/startup.js +67 -0
- package/lib/startup.js.map +1 -0
- package/lib/subagents.d.ts +74 -0
- package/lib/subagents.d.ts.map +1 -0
- package/lib/subagents.js +141 -0
- package/lib/subagents.js.map +1 -0
- package/lib/terminal/bell.d.ts +18 -0
- package/lib/terminal/bell.d.ts.map +1 -0
- package/lib/terminal/bell.js +16 -0
- package/lib/terminal/bell.js.map +1 -0
- package/lib/terminal/clipboard.d.ts +11 -0
- package/lib/terminal/clipboard.d.ts.map +1 -0
- package/lib/terminal/clipboard.js +18 -0
- package/lib/terminal/clipboard.js.map +1 -0
- package/lib/terminal/restore.d.ts +17 -0
- package/lib/terminal/restore.d.ts.map +1 -0
- package/lib/terminal/restore.js +43 -0
- package/lib/terminal/restore.js.map +1 -0
- package/lib/terminal/title.d.ts +22 -0
- package/lib/terminal/title.d.ts.map +1 -0
- package/lib/terminal/title.js +34 -0
- package/lib/terminal/title.js.map +1 -0
- package/lib/text.d.ts +19 -0
- package/lib/text.d.ts.map +1 -0
- package/lib/text.js +61 -0
- package/lib/text.js.map +1 -0
- package/lib/theme.d.ts +47 -0
- package/lib/theme.d.ts.map +1 -0
- package/lib/theme.js +84 -0
- package/lib/theme.js.map +1 -0
- package/lib/transcript.d.ts +91 -0
- package/lib/transcript.d.ts.map +1 -0
- package/lib/transcript.js +315 -0
- package/lib/transcript.js.map +1 -0
- package/lib/ui/dock.d.ts +36 -0
- package/lib/ui/dock.d.ts.map +1 -0
- package/lib/ui/dock.js +110 -0
- package/lib/ui/dock.js.map +1 -0
- package/lib/ui/markdown.d.ts +17 -0
- package/lib/ui/markdown.d.ts.map +1 -0
- package/lib/ui/markdown.js +35 -0
- package/lib/ui/markdown.js.map +1 -0
- package/lib/ui/picker.d.ts +103 -0
- package/lib/ui/picker.d.ts.map +1 -0
- package/lib/ui/picker.js +165 -0
- package/lib/ui/picker.js.map +1 -0
- package/lib/ui/rows.d.ts +30 -0
- package/lib/ui/rows.d.ts.map +1 -0
- package/lib/ui/rows.js +49 -0
- package/lib/ui/rows.js.map +1 -0
- package/lib/ui/status.d.ts +49 -0
- package/lib/ui/status.d.ts.map +1 -0
- package/lib/ui/status.js +90 -0
- package/lib/ui/status.js.map +1 -0
- package/lib/ui/view.d.ts +56 -0
- package/lib/ui/view.d.ts.map +1 -0
- package/lib/ui/view.js +184 -0
- package/lib/ui/view.js.map +1 -0
- package/lib/work.d.ts +39 -0
- package/lib/work.d.ts.map +1 -0
- package/lib/work.js +97 -0
- package/lib/work.js.map +1 -0
- package/package.json +109 -0
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
/** Sessions the picker offers before a menu stops being a menu. */
|
|
2
|
+
export const PICKER_LIMIT = 30;
|
|
3
|
+
/** Events read to title one session: enough to reach its title or first prompt. */
|
|
4
|
+
export const TITLE_EVENT_LIMIT = 40;
|
|
5
|
+
/** Longest session title the picker shows, before the row can no longer hold it. */
|
|
6
|
+
export const TITLE_CHAR_LIMIT = 72;
|
|
7
|
+
/** Events read to resolve a session's preset: a selection sits in its blank prefix. */
|
|
8
|
+
export const PRESET_EVENT_LIMIT = 40;
|
|
9
|
+
function asRecord(value) {
|
|
10
|
+
return typeof value === 'object' && value !== null ? value : undefined;
|
|
11
|
+
}
|
|
12
|
+
/** One stored header, or undefined when the snapshot carries no usable identity. */
|
|
13
|
+
function headerOf(snapshot) {
|
|
14
|
+
const entry = asRecord(snapshot);
|
|
15
|
+
const header = asRecord(entry?.header);
|
|
16
|
+
const id = header?.id;
|
|
17
|
+
if (typeof id !== 'string')
|
|
18
|
+
return undefined;
|
|
19
|
+
const eventCount = entry?.eventCount;
|
|
20
|
+
return {
|
|
21
|
+
id,
|
|
22
|
+
agentPreset: typeof header?.agentPreset === 'string' ? header.agentPreset : undefined,
|
|
23
|
+
eventCount: typeof eventCount === 'number' ? eventCount : undefined,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
function clip(title, limit) {
|
|
27
|
+
const collapsed = title.replace(/\s+/gu, ' ').trim();
|
|
28
|
+
if (collapsed === '')
|
|
29
|
+
return '';
|
|
30
|
+
return collapsed.length > limit ? `${collapsed.slice(0, limit - 1)}…` : collapsed;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Name a session, preferring the title the harness derived or the reader set.
|
|
34
|
+
*
|
|
35
|
+
* The durable `session/title` wins because it is what every other surface
|
|
36
|
+
* shows; a session that has none yet falls back to its first human prompt.
|
|
37
|
+
* Injected context and plugin notices also arrive as user-role messages, so
|
|
38
|
+
* only a direct prompt may name a session.
|
|
39
|
+
*/
|
|
40
|
+
export function sessionTitle(events, limit = TITLE_CHAR_LIMIT) {
|
|
41
|
+
for (let index = events.length - 1; index >= 0; index -= 1) {
|
|
42
|
+
const event = events[index];
|
|
43
|
+
if (event?.type !== 'session/title')
|
|
44
|
+
continue;
|
|
45
|
+
const declared = asRecord(event.data)?.title;
|
|
46
|
+
if (typeof declared !== 'string')
|
|
47
|
+
continue;
|
|
48
|
+
const title = clip(declared, limit);
|
|
49
|
+
if (title !== '')
|
|
50
|
+
return title;
|
|
51
|
+
}
|
|
52
|
+
for (const event of events) {
|
|
53
|
+
if (event.type !== 'user/message')
|
|
54
|
+
continue;
|
|
55
|
+
const data = asRecord(event.data);
|
|
56
|
+
if (asRecord(data?.source)?.kind !== 'user')
|
|
57
|
+
continue;
|
|
58
|
+
const content = Array.isArray(data?.content) ? data.content : [];
|
|
59
|
+
const parts = [];
|
|
60
|
+
for (const block of content) {
|
|
61
|
+
const text = asRecord(block)?.text;
|
|
62
|
+
if (typeof text === 'string')
|
|
63
|
+
parts.push(text);
|
|
64
|
+
}
|
|
65
|
+
const title = clip(parts.join(' '), limit);
|
|
66
|
+
if (title === '')
|
|
67
|
+
continue;
|
|
68
|
+
return title;
|
|
69
|
+
}
|
|
70
|
+
return undefined;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Title one stored session.
|
|
74
|
+
*
|
|
75
|
+
* The tail is read first because a title is latest-wins and usually written
|
|
76
|
+
* after the first turn; the head is the fallback for a session that has a
|
|
77
|
+
* prompt but no title yet.
|
|
78
|
+
*/
|
|
79
|
+
export async function readSessionTitle(history, session) {
|
|
80
|
+
const end = session.eventCount ?? 0;
|
|
81
|
+
if (end > TITLE_EVENT_LIMIT) {
|
|
82
|
+
const tail = await history.read(session.id, { offset: end - TITLE_EVENT_LIMIT, limit: TITLE_EVENT_LIMIT });
|
|
83
|
+
const declared = sessionTitle(tail);
|
|
84
|
+
if (declared !== undefined)
|
|
85
|
+
return declared;
|
|
86
|
+
}
|
|
87
|
+
return sessionTitle(await history.read(session.id, { limit: TITLE_EVENT_LIMIT }));
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* The agent preset a stored session runs.
|
|
91
|
+
*
|
|
92
|
+
* The creation header names the preset the session STARTED with, and a
|
|
93
|
+
* selection recorded while it was still blank replaced it. The projection's own
|
|
94
|
+
* rule is that the last selection wins over the header, so the tail is read
|
|
95
|
+
* first and the head second: the harness refuses a switch once a turn has run,
|
|
96
|
+
* which puts any selection in the blank prefix. Reading both keeps this correct
|
|
97
|
+
* if that rule ever loosens, and the event count bounds the work either way.
|
|
98
|
+
*/
|
|
99
|
+
export async function presetOfStoredSession(history, id) {
|
|
100
|
+
const header = await history.header(id);
|
|
101
|
+
if (header === undefined)
|
|
102
|
+
return undefined;
|
|
103
|
+
const end = header.eventCount ?? 0;
|
|
104
|
+
if (end > PRESET_EVENT_LIMIT) {
|
|
105
|
+
const tail = await lastSelection(history, id, end - PRESET_EVENT_LIMIT, PRESET_EVENT_LIMIT);
|
|
106
|
+
if (tail !== undefined)
|
|
107
|
+
return tail;
|
|
108
|
+
}
|
|
109
|
+
return await lastSelection(history, id, 0, PRESET_EVENT_LIMIT) ?? header.agentPreset;
|
|
110
|
+
}
|
|
111
|
+
/** The last recorded selection inside one slice of a session's log. */
|
|
112
|
+
async function lastSelection(history, id, offset, limit) {
|
|
113
|
+
const events = await history.read(id, { offset, limit });
|
|
114
|
+
for (let index = events.length - 1; index >= 0; index -= 1) {
|
|
115
|
+
const event = events[index];
|
|
116
|
+
if (event?.type !== 'agent-preset/selected')
|
|
117
|
+
continue;
|
|
118
|
+
const preset = asRecord(event.data)?.agentPreset;
|
|
119
|
+
if (typeof preset === 'string' && preset !== '')
|
|
120
|
+
return preset;
|
|
121
|
+
}
|
|
122
|
+
return undefined;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Wrap the persistence service in the little of it a terminal needs.
|
|
126
|
+
*
|
|
127
|
+
* The seam itself is optional here: a composition without durable storage can
|
|
128
|
+
* still run the surface, it just cannot list or replay stored sessions. A read
|
|
129
|
+
* handle is always closed, because an unclosed one keeps backend resources
|
|
130
|
+
* alive for the rest of the process.
|
|
131
|
+
*/
|
|
132
|
+
export function createSessionHistory(ctx) {
|
|
133
|
+
const service = ctx.get('sessionPersistence');
|
|
134
|
+
if (typeof service?.list !== 'function' || typeof service.open !== 'function')
|
|
135
|
+
return undefined;
|
|
136
|
+
const read = async (id, options) => {
|
|
137
|
+
const handle = (await service.open(id, 'read'));
|
|
138
|
+
try {
|
|
139
|
+
const result = await handle.read(options?.offset ?? 0, options?.limit);
|
|
140
|
+
const events = [];
|
|
141
|
+
for (const entry of result.events ?? []) {
|
|
142
|
+
const record = asRecord(entry);
|
|
143
|
+
if (typeof record?.type !== 'string')
|
|
144
|
+
continue;
|
|
145
|
+
events.push({ type: record.type, data: record.data });
|
|
146
|
+
}
|
|
147
|
+
return events;
|
|
148
|
+
}
|
|
149
|
+
finally {
|
|
150
|
+
await handle.close();
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
return {
|
|
154
|
+
read,
|
|
155
|
+
header: async (id) => {
|
|
156
|
+
const stat = service.stat;
|
|
157
|
+
return typeof stat === 'function' ? headerOf(await stat.call(service, id)) : undefined;
|
|
158
|
+
},
|
|
159
|
+
list: async (limit) => {
|
|
160
|
+
const snapshots = await service.list();
|
|
161
|
+
const sessions = [];
|
|
162
|
+
for (const entry of Array.isArray(snapshots) ? snapshots : []) {
|
|
163
|
+
const header = asRecord(asRecord(entry)?.header);
|
|
164
|
+
const id = header?.id;
|
|
165
|
+
if (typeof id !== 'string')
|
|
166
|
+
continue;
|
|
167
|
+
const eventCount = asRecord(entry)?.eventCount;
|
|
168
|
+
sessions.push({
|
|
169
|
+
id,
|
|
170
|
+
cwd: typeof header?.cwd === 'string' ? header.cwd : undefined,
|
|
171
|
+
createdAt: typeof header?.createdAt === 'number' ? header.createdAt : 0,
|
|
172
|
+
eventCount: typeof eventCount === 'number' ? eventCount : undefined,
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
return sessions.sort((left, right) => right.createdAt - left.createdAt).slice(0, limit);
|
|
176
|
+
},
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
//# sourceMappingURL=history.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"history.js","sourceRoot":"","sources":["../../src/agent/history.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
2
|
+
import type { Agent } from '@deepseek-ai/dsh-agent';
|
|
3
|
+
import { type SessionId } from '@deepseek-ai/dsh-session';
|
|
4
|
+
/** Everything the terminal surface needs to own one interactive agent. */
|
|
5
|
+
export interface TuiAgent {
|
|
6
|
+
readonly sessionId: SessionId;
|
|
7
|
+
readonly agent: Agent;
|
|
8
|
+
/** Queue an ordinary next-turn prompt from the human. */
|
|
9
|
+
submit(text: string): void;
|
|
10
|
+
/** Redirect the running turn without starting another one. */
|
|
11
|
+
steer(text: string): void;
|
|
12
|
+
/** Abort the active activity; the inbox is left alone. */
|
|
13
|
+
interrupt(): void;
|
|
14
|
+
/** Stop the loop and release the session. */
|
|
15
|
+
dispose(): Promise<void>;
|
|
16
|
+
}
|
|
17
|
+
/** History a fork inherits from the session it branches off. */
|
|
18
|
+
export interface ForkInheritance {
|
|
19
|
+
/** Session the branch starts from. */
|
|
20
|
+
readonly from: SessionId;
|
|
21
|
+
/** Contiguous prefix of that session's log, ending on a completed turn. */
|
|
22
|
+
readonly events: readonly unknown[];
|
|
23
|
+
}
|
|
24
|
+
/** Launch inputs that decide which agent this run drives. */
|
|
25
|
+
export interface StartAgentOptions {
|
|
26
|
+
readonly sessionId: SessionId;
|
|
27
|
+
readonly resume: boolean;
|
|
28
|
+
readonly model: string | undefined;
|
|
29
|
+
readonly provider: string | undefined;
|
|
30
|
+
/** Workspace for a fresh session; ignored when resuming persisted history. */
|
|
31
|
+
readonly cwd: string;
|
|
32
|
+
/**
|
|
33
|
+
* Compose the agent's own scoped world before it is published.
|
|
34
|
+
*
|
|
35
|
+
* Agent-scoped waterfalls — model selection among them — only see requests
|
|
36
|
+
* dispatched inside that scope, so they must be registered here rather than
|
|
37
|
+
* on the context that created the agent.
|
|
38
|
+
*/
|
|
39
|
+
readonly setup?: (agentCtx: Context) => void;
|
|
40
|
+
/** Branch from another session's completed history instead of starting empty. */
|
|
41
|
+
readonly fork?: ForkInheritance;
|
|
42
|
+
/**
|
|
43
|
+
* Agent preset a NEW session runs, recorded in its header.
|
|
44
|
+
*
|
|
45
|
+
* The caller mounts it in `setup`; a resume keeps the preset its own log
|
|
46
|
+
* recorded, so it never passes one.
|
|
47
|
+
*/
|
|
48
|
+
readonly preset?: string | undefined;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Create or resume the one agent this surface drives.
|
|
52
|
+
*
|
|
53
|
+
* A resume is attempted first when the launcher asked for it, because a
|
|
54
|
+
* session that exists must keep its own identity and history; a missing
|
|
55
|
+
* session is not an error the user should see, so creation is the fallback.
|
|
56
|
+
*/
|
|
57
|
+
export declare function startAgent(ctx: Context, options: StartAgentOptions): Promise<TuiAgent>;
|
|
58
|
+
//# sourceMappingURL=host.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../../src/agent/host.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAA;AACnD,OAAO,EAAuC,KAAK,SAAS,EAAE,MAAM,0BAA0B,CAAA;AAG9F,0EAA0E;AAC1E,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAA;IAC7B,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAA;IACrB,yDAAyD;IACzD,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,8DAA8D;IAC9D,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,0DAA0D;IAC1D,SAAS,IAAI,IAAI,CAAA;IACjB,6CAA6C;IAC7C,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CACzB;AAED,gEAAgE;AAChE,MAAM,WAAW,eAAe;IAC9B,sCAAsC;IACtC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;IACxB,2EAA2E;IAC3E,QAAQ,CAAC,MAAM,EAAE,SAAS,OAAO,EAAE,CAAA;CACpC;AAED,6DAA6D;AAC7D,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAA;IAC7B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAA;IAClC,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAA;IACrC,8EAA8E;IAC9E,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB;;;;;;OAMG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAA;IAC5C,iFAAiF;IACjF,QAAQ,CAAC,IAAI,CAAC,EAAE,eAAe,CAAA;IAC/B;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACrC;AAiBD;;;;;;GAMG;AACH,wBAAsB,UAAU,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,QAAQ,CAAC,CAkC5F"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { SessionLogOffset } from '@deepseek-ai/dsh-session';
|
|
2
|
+
import { createUserMessage } from '@deepseek-ai/dsh-llm';
|
|
3
|
+
function routeOf(ctx, options) {
|
|
4
|
+
if (options.model !== undefined || options.provider !== undefined) {
|
|
5
|
+
return {
|
|
6
|
+
...(options.provider === undefined ? {} : { provider: options.provider }),
|
|
7
|
+
...(options.model === undefined ? {} : { model: options.model }),
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
const selection = ctx.get('agentDefaultModel')?.currentSelection();
|
|
11
|
+
return selection === undefined ? {} : { provider: selection.provider, model: selection.model };
|
|
12
|
+
}
|
|
13
|
+
function userMessage(text) {
|
|
14
|
+
return createUserMessage({ content: [{ type: 'text', text }], source: { kind: 'user' } });
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Create or resume the one agent this surface drives.
|
|
18
|
+
*
|
|
19
|
+
* A resume is attempted first when the launcher asked for it, because a
|
|
20
|
+
* session that exists must keep its own identity and history; a missing
|
|
21
|
+
* session is not an error the user should see, so creation is the fallback.
|
|
22
|
+
*/
|
|
23
|
+
export async function startAgent(ctx, options) {
|
|
24
|
+
const agentOptions = routeOf(ctx, options);
|
|
25
|
+
const meta = { cwd: options.cwd };
|
|
26
|
+
const setup = options.setup === undefined ? {} : { setup: options.setup };
|
|
27
|
+
// A branch inherits a prefix of its parent's log, so the child is marked as
|
|
28
|
+
// seeded and carries the exact cut the host validates against.
|
|
29
|
+
const branch = options.fork === undefined
|
|
30
|
+
? {}
|
|
31
|
+
: {
|
|
32
|
+
seed: options.fork.events,
|
|
33
|
+
inheritedEventCount: SessionLogOffset(options.fork.events.length),
|
|
34
|
+
};
|
|
35
|
+
const preset = options.preset === undefined ? {} : { agentPreset: options.preset };
|
|
36
|
+
const identity = options.fork === undefined
|
|
37
|
+
? { ...meta, ...preset }
|
|
38
|
+
: { ...meta, parentSession: options.fork.from, isSeeded: true, ...preset };
|
|
39
|
+
const handle = options.resume
|
|
40
|
+
? await ctx.agents
|
|
41
|
+
.resume({ resumeSessionId: options.sessionId, agentOptions, ...setup })
|
|
42
|
+
.catch(() => ctx.agents.create({ sessionId: options.sessionId, meta: identity, agentOptions, ...branch, ...setup }))
|
|
43
|
+
: await ctx.agents.create({ sessionId: options.sessionId, meta: identity, agentOptions, ...branch, ...setup });
|
|
44
|
+
let disposed = false;
|
|
45
|
+
return {
|
|
46
|
+
sessionId: options.sessionId,
|
|
47
|
+
agent: handle.agent,
|
|
48
|
+
submit: text => handle.agent.followup(userMessage(text)),
|
|
49
|
+
steer: text => handle.agent.steer(userMessage(text)),
|
|
50
|
+
interrupt: () => handle.agent.cancel({ kind: 'user' }),
|
|
51
|
+
dispose: async () => {
|
|
52
|
+
if (disposed)
|
|
53
|
+
return;
|
|
54
|
+
disposed = true;
|
|
55
|
+
await handle.dispose();
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=host.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"host.js","sourceRoot":"","sources":["../../src/agent/host.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAqC,MAAM,0BAA0B,CAAA;AAC9F,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAmDxD,SAAS,OAAO,CAAC,GAAY,EAAE,OAA0B;IACvD,IAAI,OAAO,CAAC,KAAK,KAAK,SAAS,IAAI,OAAO,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;QAClE,OAAO;YACL,GAAG,CAAC,OAAO,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC;YACzE,GAAG,CAAC,OAAO,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC;SACjE,CAAA;IACH,CAAC;IACD,MAAM,SAAS,GAAG,GAAG,CAAC,GAAG,CAAC,mBAAmB,CAAC,EAAE,gBAAgB,EAAE,CAAA;IAClE,OAAO,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,SAAS,CAAC,QAAQ,EAAE,KAAK,EAAE,SAAS,CAAC,KAAK,EAAE,CAAA;AAChG,CAAC;AAED,SAAS,WAAW,CAAC,IAAY;IAC/B,OAAO,iBAAiB,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,CAAA;AAC3F,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,GAAY,EAAE,OAA0B;IACvE,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;IAC1C,MAAM,IAAI,GAAG,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,CAAA;IACjC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAA;IACzE,4EAA4E;IAC5E,+DAA+D;IAC/D,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,KAAK,SAAS;QACvC,CAAC,CAAC,EAAE;QACJ,CAAC,CAAC;YACE,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,MAAiC;YACpD,mBAAmB,EAAE,gBAAgB,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;SAClE,CAAA;IACL,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,MAAM,EAAE,CAAA;IAClF,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,KAAK,SAAS;QACzC,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,GAAG,MAAM,EAAE;QACxB,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,aAAa,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,MAAM,EAAE,CAAA;IAC5E,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM;QAC3B,CAAC,CAAC,MAAM,GAAG,CAAC,MAAM;aACb,MAAM,CAAC,EAAE,eAAe,EAAE,OAAO,CAAC,SAAS,EAAE,YAAY,EAAE,GAAG,KAAK,EAAE,CAAC;aACtE,KAAK,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,GAAG,MAAM,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC;QACxH,CAAC,CAAC,MAAM,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,GAAG,MAAM,EAAE,GAAG,KAAK,EAAE,CAAC,CAAA;IAChH,IAAI,QAAQ,GAAG,KAAK,CAAA;IACpB,OAAO;QACL,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QACxD,KAAK,EAAE,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QACpD,SAAS,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;QACtD,OAAO,EAAE,KAAK,IAAI,EAAE;YAClB,IAAI,QAAQ;gBAAE,OAAM;YACpB,QAAQ,GAAG,IAAI,CAAA;YACf,MAAM,MAAM,CAAC,OAAO,EAAE,CAAA;QACxB,CAAC;KACF,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
2
|
+
/** The route a reader chose for the next step. */
|
|
3
|
+
export interface ModelChoice {
|
|
4
|
+
readonly provider: string;
|
|
5
|
+
readonly model: string;
|
|
6
|
+
readonly reasoningEffort?: string;
|
|
7
|
+
}
|
|
8
|
+
/** One provider a session may route through. */
|
|
9
|
+
export interface ProviderEntry {
|
|
10
|
+
readonly id: string;
|
|
11
|
+
readonly name: string;
|
|
12
|
+
}
|
|
13
|
+
/** What a `/model` argument asks the surface to do. */
|
|
14
|
+
export type ModelCommand = {
|
|
15
|
+
readonly kind: 'current';
|
|
16
|
+
} | {
|
|
17
|
+
readonly kind: 'list-models';
|
|
18
|
+
readonly provider: string;
|
|
19
|
+
} | {
|
|
20
|
+
readonly kind: 'switch';
|
|
21
|
+
readonly choice: ModelChoice;
|
|
22
|
+
} | {
|
|
23
|
+
readonly kind: 'invalid';
|
|
24
|
+
readonly reason: string;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Read a `/model` argument.
|
|
28
|
+
*
|
|
29
|
+
* The forms are deliberately unambiguous: a bare argument that names a provider
|
|
30
|
+
* lists that provider's models, `provider/model` switches, and anything else is
|
|
31
|
+
* taken as a model id inside the route already in use, because a reader
|
|
32
|
+
* switching between two models of one provider should not have to repeat it.
|
|
33
|
+
*/
|
|
34
|
+
export declare function parseModelArgument(argument: string, providers: readonly ProviderEntry[], current: ModelChoice | undefined): ModelCommand;
|
|
35
|
+
/**
|
|
36
|
+
* Own the reader's model choice for one session.
|
|
37
|
+
*
|
|
38
|
+
* The choice is applied through the agent's own scoped waterfalls, so it takes
|
|
39
|
+
* effect on the next step rather than splitting an in-flight request, and the
|
|
40
|
+
* loop logs its own durable notice when the route actually changes.
|
|
41
|
+
*/
|
|
42
|
+
export declare class ModelSwitch {
|
|
43
|
+
private readonly selection;
|
|
44
|
+
private installed;
|
|
45
|
+
/** Compose the switch into the agent's scope, where the waterfalls are dispatched. */
|
|
46
|
+
install(agentCtx: Context): void;
|
|
47
|
+
choose(choice: ModelChoice): void;
|
|
48
|
+
current(): ModelChoice | undefined;
|
|
49
|
+
/** Forget the choice, so the session returns to the composition default. */
|
|
50
|
+
reset(): void;
|
|
51
|
+
dispose(): void;
|
|
52
|
+
}
|
|
53
|
+
/** Read the advisory catalog of routes this composition can reach. */
|
|
54
|
+
export declare function createModelCatalog(ctx: Context): {
|
|
55
|
+
providers(): readonly ProviderEntry[];
|
|
56
|
+
models(provider: string): Promise<readonly {
|
|
57
|
+
readonly id: string;
|
|
58
|
+
readonly name: string;
|
|
59
|
+
}[]>;
|
|
60
|
+
} | undefined;
|
|
61
|
+
//# sourceMappingURL=model.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../src/agent/model.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAElD,kDAAkD;AAClD,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAA;CAClC;AAED,gDAAgD;AAChD,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACtB;AAED,uDAAuD;AACvD,MAAM,MAAM,YAAY,GACpB;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;CAAE,GAC5B;IAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAC3D;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAA;CAAE,GACzD;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAA;AAEzD;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,SAAS,aAAa,EAAE,EACnC,OAAO,EAAE,WAAW,GAAG,SAAS,GAC/B,YAAY,CAgBd;AAED;;;;;;GAMG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAkE;IAC5F,OAAO,CAAC,SAAS,CAA0B;IAE3C,sFAAsF;IACtF,OAAO,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI;IAKhC,MAAM,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI;IAUjC,OAAO,IAAI,WAAW,GAAG,SAAS;IAUlC,4EAA4E;IAC5E,KAAK,IAAI,IAAI;IAKb,OAAO,IAAI,IAAI;CAIhB;AAQD,sEAAsE;AACtE,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG;IAChD,SAAS,IAAI,SAAS,aAAa,EAAE,CAAA;IACrC,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS;QAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC,CAAA;CAC7F,GAAG,SAAS,CAeZ"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { installModelSelection } from '@deepseek-ai/dsh-agent';
|
|
2
|
+
import { ReasoningEffortId } from '@deepseek-ai/dsh-llm';
|
|
3
|
+
/**
|
|
4
|
+
* Read a `/model` argument.
|
|
5
|
+
*
|
|
6
|
+
* The forms are deliberately unambiguous: a bare argument that names a provider
|
|
7
|
+
* lists that provider's models, `provider/model` switches, and anything else is
|
|
8
|
+
* taken as a model id inside the route already in use, because a reader
|
|
9
|
+
* switching between two models of one provider should not have to repeat it.
|
|
10
|
+
*/
|
|
11
|
+
export function parseModelArgument(argument, providers, current) {
|
|
12
|
+
const trimmed = argument.trim();
|
|
13
|
+
if (trimmed === '')
|
|
14
|
+
return { kind: 'current' };
|
|
15
|
+
const slash = trimmed.indexOf('/');
|
|
16
|
+
if (slash > 0 && slash < trimmed.length - 1) {
|
|
17
|
+
return { kind: 'switch', choice: { provider: trimmed.slice(0, slash), model: trimmed.slice(slash + 1) } };
|
|
18
|
+
}
|
|
19
|
+
if (providers.some(provider => provider.id === trimmed))
|
|
20
|
+
return { kind: 'list-models', provider: trimmed };
|
|
21
|
+
if (current === undefined) {
|
|
22
|
+
const names = providers.map(provider => provider.id).join(', ');
|
|
23
|
+
return {
|
|
24
|
+
kind: 'invalid',
|
|
25
|
+
reason: `no route in use; say /model <provider>/${trimmed}${names === '' ? '' : ` — providers: ${names}`}`,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
return { kind: 'switch', choice: { provider: current.provider, model: trimmed } };
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Own the reader's model choice for one session.
|
|
32
|
+
*
|
|
33
|
+
* The choice is applied through the agent's own scoped waterfalls, so it takes
|
|
34
|
+
* effect on the next step rather than splitting an in-flight request, and the
|
|
35
|
+
* loop logs its own durable notice when the route actually changes.
|
|
36
|
+
*/
|
|
37
|
+
export class ModelSwitch {
|
|
38
|
+
selection = { current: undefined, assembled: undefined };
|
|
39
|
+
installed;
|
|
40
|
+
/** Compose the switch into the agent's scope, where the waterfalls are dispatched. */
|
|
41
|
+
install(agentCtx) {
|
|
42
|
+
this.installed?.();
|
|
43
|
+
this.installed = installModelSelection(agentCtx, this.selection);
|
|
44
|
+
}
|
|
45
|
+
choose(choice) {
|
|
46
|
+
this.selection.current = {
|
|
47
|
+
provider: choice.provider,
|
|
48
|
+
model: choice.model,
|
|
49
|
+
...choice.reasoningEffort === undefined
|
|
50
|
+
? {}
|
|
51
|
+
: { reasoningEffort: ReasoningEffortId(choice.reasoningEffort) },
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
current() {
|
|
55
|
+
const current = this.selection.current;
|
|
56
|
+
if (current === undefined)
|
|
57
|
+
return undefined;
|
|
58
|
+
return {
|
|
59
|
+
provider: current.provider,
|
|
60
|
+
model: current.model,
|
|
61
|
+
...current.reasoningEffort === undefined ? {} : { reasoningEffort: String(current.reasoningEffort) },
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
/** Forget the choice, so the session returns to the composition default. */
|
|
65
|
+
reset() {
|
|
66
|
+
this.selection.current = undefined;
|
|
67
|
+
this.selection.assembled = undefined;
|
|
68
|
+
}
|
|
69
|
+
dispose() {
|
|
70
|
+
this.installed?.();
|
|
71
|
+
this.installed = undefined;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/** Read the advisory catalog of routes this composition can reach. */
|
|
75
|
+
export function createModelCatalog(ctx) {
|
|
76
|
+
const llm = ctx.get('llm');
|
|
77
|
+
if (typeof llm?.listProviders !== 'function')
|
|
78
|
+
return undefined;
|
|
79
|
+
const providers = () => (llm.listProviders?.() ?? []).flatMap(entry => typeof entry.id === 'string' ? [{ id: entry.id, name: typeof entry.name === 'string' ? entry.name : entry.id }] : []);
|
|
80
|
+
return {
|
|
81
|
+
providers,
|
|
82
|
+
models: async (provider) => {
|
|
83
|
+
if (typeof llm.listModels !== 'function')
|
|
84
|
+
return [];
|
|
85
|
+
const models = await llm.listModels(provider);
|
|
86
|
+
return models.flatMap(entry => typeof entry.id === 'string'
|
|
87
|
+
? [{ id: entry.id, name: typeof entry.name === 'string' ? entry.name : entry.id }]
|
|
88
|
+
: []);
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=model.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model.js","sourceRoot":"","sources":["../../src/agent/model.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
2
|
+
import { type ToolPresenter } from '../cards.ts';
|
|
3
|
+
/**
|
|
4
|
+
* Present tool calls and results through each tool's own render intent.
|
|
5
|
+
*
|
|
6
|
+
* The surface must not know tool names: a tool package declares how its call
|
|
7
|
+
* and result read. An unknown tool, a missing presenter, or a throwing one
|
|
8
|
+
* degrades to the generic card instead of breaking the transcript, because a
|
|
9
|
+
* broken card is recoverable and a broken transcript is not.
|
|
10
|
+
*/
|
|
11
|
+
export declare function createToolPresenter(ctx: Context): ToolPresenter;
|
|
12
|
+
//# sourceMappingURL=present.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"present.d.ts","sourceRoot":"","sources":["../../src/agent/present.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,EAIL,KAAK,aAAa,EAEnB,MAAM,aAAa,CAAA;AAUpB;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,OAAO,GAAG,aAAa,CAiC/D"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { cardOfCall, cardOfResult, contentLines, } from "../cards.js";
|
|
2
|
+
function parseArguments(argumentsJson) {
|
|
3
|
+
try {
|
|
4
|
+
return JSON.parse(argumentsJson);
|
|
5
|
+
}
|
|
6
|
+
catch {
|
|
7
|
+
return undefined;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Present tool calls and results through each tool's own render intent.
|
|
12
|
+
*
|
|
13
|
+
* The surface must not know tool names: a tool package declares how its call
|
|
14
|
+
* and result read. An unknown tool, a missing presenter, or a throwing one
|
|
15
|
+
* degrades to the generic card instead of breaking the transcript, because a
|
|
16
|
+
* broken card is recoverable and a broken transcript is not.
|
|
17
|
+
*/
|
|
18
|
+
export function createToolPresenter(ctx) {
|
|
19
|
+
const definition = (name) => {
|
|
20
|
+
try {
|
|
21
|
+
return ctx.tools.get(name);
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
return {
|
|
28
|
+
call(name, argumentsJson) {
|
|
29
|
+
try {
|
|
30
|
+
const view = definition(name)?.presentCall?.(parseArguments(argumentsJson));
|
|
31
|
+
return cardOfCall(view, name);
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
result(name, input) {
|
|
38
|
+
try {
|
|
39
|
+
const view = definition(name)?.presentResult?.(parseArguments(input.argumentsJson), { content: input.content, isError: input.isError, meta: input.meta });
|
|
40
|
+
return cardOfResult(view, {
|
|
41
|
+
fallbackTitle: name,
|
|
42
|
+
failed: input.isError,
|
|
43
|
+
contentLines: contentLines(input.content),
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
return undefined;
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=present.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"present.js","sourceRoot":"","sources":["../../src/agent/present.ts"],"names":[],"mappings":"AACA,OAAO,EACL,UAAU,EACV,YAAY,EACZ,YAAY,GAGb,MAAM,aAAa,CAAA;AAEpB,SAAS,cAAc,CAAC,aAAqB;IAC3C,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,aAAa,CAAY,CAAA;IAC7C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAA;IAClB,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,mBAAmB,CAAC,GAAY;IAC9C,MAAM,UAAU,GAAG,CAAC,IAAY,EAAE,EAAE;QAClC,IAAI,CAAC;YACH,OAAO,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QAC5B,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,SAAS,CAAA;QAClB,CAAC;IACH,CAAC,CAAA;IACD,OAAO;QACL,IAAI,CAAC,IAAI,EAAE,aAAa;YACtB,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,EAAE,WAAW,EAAE,CAAC,cAAc,CAAC,aAAa,CAAU,CAAC,CAAA;gBACpF,OAAO,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;YAC/B,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,SAAS,CAAA;YAClB,CAAC;QACH,CAAC;QACD,MAAM,CAAC,IAAI,EAAE,KAAsB;YACjC,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,EAAE,aAAa,EAAE,CAC5C,cAAc,CAAC,KAAK,CAAC,aAAa,CAAU,EAC5C,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAW,CAC9E,CAAA;gBACD,OAAO,YAAY,CAAC,IAAI,EAAE;oBACxB,aAAa,EAAE,IAAI;oBACnB,MAAM,EAAE,KAAK,CAAC,OAAO;oBACrB,YAAY,EAAE,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC;iBAC1C,CAAC,CAAA;YACJ,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,SAAS,CAAA;YAClB,CAAC;QACH,CAAC;KACF,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
2
|
+
import type { PickerRow } from '../ui/picker.ts';
|
|
3
|
+
/**
|
|
4
|
+
* The roster of agent compositions, and the mode one session runs.
|
|
5
|
+
*
|
|
6
|
+
* A preset is the plugin composition an agent's own scope joins: its tools,
|
|
7
|
+
* prompt sections, skills, and planning rows. The session header records the
|
|
8
|
+
* one it started with, a switch while the session is still blank is recorded as
|
|
9
|
+
* a `agent-preset/selected` event, and the `agentPreset` projection is the
|
|
10
|
+
* answer every reader resolves — the header alone is not.
|
|
11
|
+
*/
|
|
12
|
+
/** One preset as the roster publishes it. */
|
|
13
|
+
export interface PresetSummary {
|
|
14
|
+
readonly id: string;
|
|
15
|
+
readonly trust: 'system' | 'user';
|
|
16
|
+
/** Display text the preset itself published, when it published any. */
|
|
17
|
+
readonly name: string | undefined;
|
|
18
|
+
readonly description: string | undefined;
|
|
19
|
+
/** Why this preset cannot compose a session, absent when it can. */
|
|
20
|
+
readonly broken: string | undefined;
|
|
21
|
+
}
|
|
22
|
+
/** What a `/preset` argument asks the surface to do. */
|
|
23
|
+
export type PresetCommand = {
|
|
24
|
+
readonly kind: 'pick';
|
|
25
|
+
} | {
|
|
26
|
+
readonly kind: 'switch';
|
|
27
|
+
readonly id: string;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Read a `/preset` argument.
|
|
31
|
+
*
|
|
32
|
+
* A bare command opens the picker because choosing by eye is the point of a
|
|
33
|
+
* selector; anything else is an id, which is the token the session log records.
|
|
34
|
+
*/
|
|
35
|
+
export declare function parsePresetArgument(argument: string): PresetCommand;
|
|
36
|
+
/** How one preset appears in the picker. */
|
|
37
|
+
export declare function describePreset(preset: PresetSummary, currentId: string | undefined): PickerRow;
|
|
38
|
+
/** The roster this surface reads, described structurally. */
|
|
39
|
+
export interface PresetRoster {
|
|
40
|
+
/** The preset a session starts on when nobody names one. */
|
|
41
|
+
readonly defaultId: string;
|
|
42
|
+
list(): Promise<readonly PresetSummary[]>;
|
|
43
|
+
resolve(id: string | undefined): Promise<PresetSummary>;
|
|
44
|
+
/**
|
|
45
|
+
* Join one unpublished agent scope to its preset.
|
|
46
|
+
*
|
|
47
|
+
* A rejection here rolls the whole agent creation back, so a preset that
|
|
48
|
+
* cannot compose never yields a half-configured session.
|
|
49
|
+
*/
|
|
50
|
+
mount(agentCtx: Context, id: string): Promise<void>;
|
|
51
|
+
/** Compose a blank session's agent from another preset and record it. */
|
|
52
|
+
select(agent: unknown, id: string): Promise<string>;
|
|
53
|
+
/** The preset one live session runs, from its own projection. */
|
|
54
|
+
current(session: unknown): string | undefined;
|
|
55
|
+
/**
|
|
56
|
+
* Whether a session has produced a turn, which is what fixes its preset.
|
|
57
|
+
*
|
|
58
|
+
* Read as the harness reads it, and only to keep the picker from offering a
|
|
59
|
+
* choice that would be refused: {@link PresetRoster.select} remains the
|
|
60
|
+
* authority, because a session can start between this read and the switch.
|
|
61
|
+
*/
|
|
62
|
+
started(session: unknown): boolean;
|
|
63
|
+
}
|
|
64
|
+
/** The projection key the roster advances and this surface reads. */
|
|
65
|
+
export declare const AGENT_PRESET_KEY = "agentPreset";
|
|
66
|
+
/**
|
|
67
|
+
* Wrap the roster in the little of it a terminal needs.
|
|
68
|
+
*
|
|
69
|
+
* The seam is optional here: a composition that dropped the row still runs the
|
|
70
|
+
* surface, it just has no mode to choose. Every call is guarded because the
|
|
71
|
+
* service arrives from another package and its shape is this surface's
|
|
72
|
+
* assumption, not its contract.
|
|
73
|
+
*/
|
|
74
|
+
export declare function createPresetRoster(ctx: Context): PresetRoster | undefined;
|
|
75
|
+
//# sourceMappingURL=presets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"presets.d.ts","sourceRoot":"","sources":["../../src/agent/presets.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAGhD;;;;;;;;GAQG;AAEH,6CAA6C;AAC7C,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM,CAAA;IACjC,uEAAuE;IACvE,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAA;IACjC,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,CAAA;IACxC,oEAAoE;IACpE,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAA;CACpC;AAED,wDAAwD;AACxD,MAAM,MAAM,aAAa,GACrB;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACzB;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAA;AAEpD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa,CAGnE;AAgBD,4CAA4C;AAC5C,wBAAgB,cAAc,CAAC,MAAM,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAa9F;AAED,6DAA6D;AAC7D,MAAM,WAAW,YAAY;IAC3B,4DAA4D;IAC5D,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,IAAI,IAAI,OAAO,CAAC,SAAS,aAAa,EAAE,CAAC,CAAA;IACzC,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,CAAA;IACvD;;;;;OAKG;IACH,KAAK,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACnD,yEAAyE;IACzE,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;IACnD,iEAAiE;IACjE,OAAO,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAAA;IAC7C;;;;;;OAMG;IACH,OAAO,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAA;CACnC;AAED,qEAAqE;AACrE,eAAO,MAAM,gBAAgB,gBAAgB,CAAA;AAwC7C;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG,YAAY,GAAG,SAAS,CAoCzE"}
|