dsh-codebuddy-llm 0.0.0-stage → 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 +129 -2
- package/README.zh.md +130 -0
- package/cordis.patch.yml +38 -0
- package/index.js +1672 -0
- package/package.json +67 -4
- package/types/acp.d.ts +177 -0
- package/types/adapter.d.ts +166 -0
- package/types/config.d.ts +186 -0
- package/types/discovery.d.ts +57 -0
- package/types/index.d.ts +43 -0
- package/types/translate.d.ts +73 -0
- package/types/wire.d.ts +57 -0
package/types/index.d.ts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `llm-cli`: a provider route answered by a CLI child instead of a provider HTTP
|
|
3
|
+
* endpoint.
|
|
4
|
+
*
|
|
5
|
+
* The route exists so a deployment can run the harness with no API key at all:
|
|
6
|
+
* the configured CLI (CodeBuddy by default) carries its own authentication and
|
|
7
|
+
* runs its own agentic loop with its own tools. The harness forwards
|
|
8
|
+
* conversation text and receives the final answer, so a model swap is a
|
|
9
|
+
* configuration change rather than a harness change.
|
|
10
|
+
*
|
|
11
|
+
* The plugin depends on exactly two seams — `llm` (the adapter registry) and
|
|
12
|
+
* `subprocess` (child lifecycle) — and reaches the session store, when a
|
|
13
|
+
* deployment has one, through an untyped service lookup. Nothing here requires
|
|
14
|
+
* `dsh-session`, a remote surface, or a client package, so mounting it changes
|
|
15
|
+
* no shared package.
|
|
16
|
+
*
|
|
17
|
+
* ```yaml
|
|
18
|
+
* - id: llm-cli
|
|
19
|
+
* name: 'dsh-codebuddy-llm'
|
|
20
|
+
* config:
|
|
21
|
+
* command: codebuddy
|
|
22
|
+
* args: ['--print', '--output-format', 'stream-json', '--include-partial-messages']
|
|
23
|
+
* permissionMode: bypassPermissions
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* @module dsh-codebuddy-llm
|
|
27
|
+
*/
|
|
28
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
29
|
+
import { Config } from './config.js';
|
|
30
|
+
export { CliAdapter, CLI_TRANSPORTS, CODEBUDDY_EFFORT_LEVELS, CODEBUDDY_PERMISSION_MODES, DEFAULT_TRANSPORT, } from './adapter.js';
|
|
31
|
+
export type { CliAdapterOptions, CliCatalogModel, CliConnectionOptions, CliTransport, CodeBuddyEffort, CodeBuddyPermissionMode, } from './adapter.js';
|
|
32
|
+
export { AcpTransport } from './acp.js';
|
|
33
|
+
export type { AcpCatalogModel, AcpPermissionOption, AcpPromptOutcome, AcpTransportOptions, AcpTurnEvent } from './acp.js';
|
|
34
|
+
export { Config, DEFAULT_ARGS, DEFAULT_COMMAND, DEFAULT_DISPOSE_GRACE_MS, DEFAULT_MODEL_DISCOVERY_ARGS, DEFAULT_MODEL_DISCOVERY_TIMEOUT_MS, DEFAULT_PERMISSION_MODE, DEFAULT_SESSION_ID_ARG, plainOptions, resolveAdapterOptions, } from './config.js';
|
|
35
|
+
export type { Options, ResolvedCliOptions } from './config.js';
|
|
36
|
+
export { discoverCliModels, parseCodeBuddyModels } from './discovery.js';
|
|
37
|
+
export * from './translate.js';
|
|
38
|
+
export * from './wire.js';
|
|
39
|
+
export declare const name = "llm-cli";
|
|
40
|
+
export declare const inject: string[];
|
|
41
|
+
/** Register the CLI route, its settings section, and its model discovery. */
|
|
42
|
+
export declare function apply(ctx: Context, config: Config): void;
|
|
43
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Message translation for the CLI adapter: turns harness conversation content
|
|
3
|
+
* into the prompt text one CLI child run consumes, and lifts the system prompt
|
|
4
|
+
* out of the history into the CLI's own system-prompt slot.
|
|
5
|
+
*
|
|
6
|
+
* The delegated CLI runs its own agentic loop with its own tools, so no harness
|
|
7
|
+
* tool vocabulary crosses the boundary; only human-authored user text and prior
|
|
8
|
+
* assistant answers do, and the CLI's own session (keyed by the harness session
|
|
9
|
+
* id) owns its tool history.
|
|
10
|
+
*
|
|
11
|
+
* @module dsh-codebuddy-llm/translate
|
|
12
|
+
*/
|
|
13
|
+
import type { RequestMessage } from '@deepseek-ai/dsh-llm';
|
|
14
|
+
/**
|
|
15
|
+
* Flatten one message's text content into consecutive lines.
|
|
16
|
+
* @param message - the harness message to flatten.
|
|
17
|
+
* @returns its text blocks, in order.
|
|
18
|
+
*/
|
|
19
|
+
export declare function textBlocksOf(message: RequestMessage): string[];
|
|
20
|
+
/**
|
|
21
|
+
* The rendered system prompt a request carries.
|
|
22
|
+
*
|
|
23
|
+
* Two request shapes reach an adapter, and they carry the prompt differently: a
|
|
24
|
+
* loop-built request passes its derived history, whose leading system-role
|
|
25
|
+
* message is the prompt, and leaves `GenerateOptions.system` undefined; a
|
|
26
|
+
* hand-built one-shot may fill that field instead. Reading both — preferring
|
|
27
|
+
* the explicit field — is what keeps the prompt from being silently dropped on
|
|
28
|
+
* either path. System blocks are concatenated without a separator, matching the
|
|
29
|
+
* projection `dsh-llm-deepseek` applies to the same history so both routes read
|
|
30
|
+
* one session alike.
|
|
31
|
+
* @param messages - ordered conversation messages.
|
|
32
|
+
* @param system - the request's explicit system slot, when it has one.
|
|
33
|
+
* @returns the system prompt text, or undefined when the request carries none.
|
|
34
|
+
*/
|
|
35
|
+
export declare function systemTextOf(messages: readonly RequestMessage[], system?: string): string | undefined;
|
|
36
|
+
/**
|
|
37
|
+
* Flatten the harness conversation into one prompt text for a stateless call.
|
|
38
|
+
*
|
|
39
|
+
* Plugin-injected user-role context is user-role conversation and therefore
|
|
40
|
+
* *is* forwarded here: a stateless call has no CLI-side history, so dropping it
|
|
41
|
+
* would hand the CLI a different conversation than the harness model would have
|
|
42
|
+
* seen. That is the opposite of {@link trailingUserText}, where the same
|
|
43
|
+
* injected text must not displace the human's newest input.
|
|
44
|
+
*
|
|
45
|
+
* @param messages - ordered conversation messages.
|
|
46
|
+
* @returns the complete prompt, or `undefined` when nothing text-worthy exists.
|
|
47
|
+
*/
|
|
48
|
+
export declare function flattenConversation(messages: readonly RequestMessage[]): string | undefined;
|
|
49
|
+
/**
|
|
50
|
+
* The conversation as it stood before the newest human input, for a delegated
|
|
51
|
+
* CLI that owns no history of it.
|
|
52
|
+
*
|
|
53
|
+
* The ACP transport keeps the CLI's own session alive, so an ongoing
|
|
54
|
+
* conversation normally never needs this. It is the fallback for the cases
|
|
55
|
+
* where that session is gone — a restarted harness, a replaced child, or a CLI
|
|
56
|
+
* that refused to resume one — and the CLI would otherwise answer the newest
|
|
57
|
+
* message knowing nothing that came before it.
|
|
58
|
+
*
|
|
59
|
+
* @param messages - ordered conversation messages.
|
|
60
|
+
* @returns the prior turns, or `undefined` when only the newest input exists.
|
|
61
|
+
*/
|
|
62
|
+
export declare function conversationRecap(messages: readonly RequestMessage[]): string | undefined;
|
|
63
|
+
/**
|
|
64
|
+
* Extract the trailing human-authored user text of a conversation. A
|
|
65
|
+
* persistent session forwards only the newest human input, because the CLI
|
|
66
|
+
* already knows the history under the session id. Plugin context also uses the
|
|
67
|
+
* user role, so the message source — not the role alone — is what distinguishes
|
|
68
|
+
* the human's words from an injected context message that must not replace them.
|
|
69
|
+
* @param messages - ordered conversation messages.
|
|
70
|
+
* @returns the last human-authored user text, or `undefined` when none exists.
|
|
71
|
+
*/
|
|
72
|
+
export declare function trailingUserText(messages: readonly RequestMessage[]): string | undefined;
|
|
73
|
+
//# sourceMappingURL=translate.d.ts.map
|
package/types/wire.d.ts
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Line-protocol parsing for a CLI child's stream-json output. CodeBuddy-style
|
|
3
|
+
* CLIs emit one JSON object per line; this parser owns line framing, the event
|
|
4
|
+
* vocabulary it understands, and the text-delta computation.
|
|
5
|
+
*
|
|
6
|
+
* Two line families carry answer text, and a run may produce either or both:
|
|
7
|
+
* `stream_event` frames wrap the model request's own SSE events when the child
|
|
8
|
+
* is asked for partial messages, so text arrives while it is still being
|
|
9
|
+
* generated; and the completed `assistant` frame repeats the whole message once
|
|
10
|
+
* the message ends. Both are measured against the text already observed *for
|
|
11
|
+
* the message in progress*, which is why `message_start` is reported rather
|
|
12
|
+
* than ignored — it is the only boundary a caller has for resetting that
|
|
13
|
+
* measurement. A frame adding nothing beyond the text already seen is ignored,
|
|
14
|
+
* so a run reading both families emits each character once.
|
|
15
|
+
*
|
|
16
|
+
* Unknown events are ignored: the event vocabulary is merge-extensible and this
|
|
17
|
+
* adapter only consumes what it maps.
|
|
18
|
+
*
|
|
19
|
+
* @module dsh-codebuddy-llm/wire
|
|
20
|
+
*/
|
|
21
|
+
import type { LlmFailure, TokenUsage } from '@deepseek-ai/dsh-llm';
|
|
22
|
+
/** One emitted text delta, from a partial message or from a completed one. */
|
|
23
|
+
export interface CliTextDelta {
|
|
24
|
+
/** Newly observed text since the previous frame of the message in progress. */
|
|
25
|
+
text: string;
|
|
26
|
+
}
|
|
27
|
+
/** Terminal outcome of one CLI run, as reported by its result event. */
|
|
28
|
+
export type CliTerminal = {
|
|
29
|
+
kind: 'stop';
|
|
30
|
+
sessionId?: string;
|
|
31
|
+
usage?: TokenUsage;
|
|
32
|
+
} | {
|
|
33
|
+
kind: 'max-turns';
|
|
34
|
+
} | {
|
|
35
|
+
kind: 'error';
|
|
36
|
+
failure: LlmFailure;
|
|
37
|
+
};
|
|
38
|
+
/** What one parsed line contributes to the adapter. */
|
|
39
|
+
export type CliLineEvent = {
|
|
40
|
+
kind: 'message-start';
|
|
41
|
+
} | {
|
|
42
|
+
kind: 'text';
|
|
43
|
+
delta: CliTextDelta;
|
|
44
|
+
} | {
|
|
45
|
+
kind: 'terminal';
|
|
46
|
+
terminal: CliTerminal;
|
|
47
|
+
} | {
|
|
48
|
+
kind: 'ignored';
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Parse one line of CLI stream-json output.
|
|
52
|
+
* @param line - one raw stdout line (already stripped of its newline).
|
|
53
|
+
* @param lastText - the text observed so far for the message in progress; a delta is measured against it.
|
|
54
|
+
* @returns the event this line contributes, or undefined when the line is blank.
|
|
55
|
+
*/
|
|
56
|
+
export declare function parseCliLine(line: string, lastText: string): CliLineEvent | undefined;
|
|
57
|
+
//# sourceMappingURL=wire.d.ts.map
|