@adaptiqai/deepseek-harness 0.0.0-stage → 0.2.2
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 +114 -2
- package/assets/fonts/Manrope-OFL.txt +93 -0
- package/cordis.patch.yml +7 -0
- package/icon.svg +10 -0
- package/lib/client.js +7 -0
- package/lib/index.js +4181 -0
- package/lib/typert.host.d.ts +3 -0
- package/lib/typert.host.js +560 -0
- package/lib/typert.remote-client.d.ts +5 -0
- package/lib/typert.remote-client.js +360 -0
- package/lib/types/client/Access.d.ts +33 -0
- package/lib/types/client/Connect.d.ts +18 -0
- package/lib/types/client/Extras.d.ts +34 -0
- package/lib/types/client/Knowledge.d.ts +35 -0
- package/lib/types/client/MemoryPill.d.ts +21 -0
- package/lib/types/client/Overlay.d.ts +29 -0
- package/lib/types/client/SettingsPage.d.ts +22 -0
- package/lib/types/client/actions.d.ts +87 -0
- package/lib/types/client/index.d.ts +15 -0
- package/lib/types/client/model.d.ts +37 -0
- package/lib/types/client/store.d.ts +112 -0
- package/lib/types/client/styles/fonts.d.ts +1 -0
- package/lib/types/client/ui.d.ts +69 -0
- package/lib/types/host/adapter.d.ts +54 -0
- package/lib/types/host/commands.d.ts +17 -0
- package/lib/types/host/config.d.ts +33 -0
- package/lib/types/host/controller.d.ts +85 -0
- package/lib/types/host/index.d.ts +12 -0
- package/lib/types/host/stores.d.ts +27 -0
- package/lib/types/host/stream.d.ts +25 -0
- package/lib/types/host/tools.d.ts +14 -0
- package/lib/types/host/wire.d.ts +62 -0
- package/locale/da.json +6 -0
- package/locale/en.json +6 -0
- package/locale/zh.json +6 -0
- package/package.json +106 -3
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { AccountSnapshot, SessionView } from '@adaptiqai/core/types';
|
|
2
|
+
import type { Kit, ModelChoice } from './actions.ts';
|
|
3
|
+
/** The harness's standard projection hook on session-scoped slots. */
|
|
4
|
+
export type UseProjection = (key: string) => unknown;
|
|
5
|
+
/**
|
|
6
|
+
* The composer's next model and the one the conversation last ran on.
|
|
7
|
+
* @param useProjection - the slot's standard hook, when the harness passes it.
|
|
8
|
+
* @returns both, or undefined while unknown.
|
|
9
|
+
*/
|
|
10
|
+
export declare function useSelection(kit: Kit, sessionId: string, useProjection: UseProjection | undefined): {
|
|
11
|
+
next: ModelChoice | null;
|
|
12
|
+
lastUsed: ModelChoice | null;
|
|
13
|
+
} | undefined;
|
|
14
|
+
/**
|
|
15
|
+
* Report the conversation's AdaptiqAI model to the Host, which keeps knowledge
|
|
16
|
+
* and memory on the right model before the first message is sent.
|
|
17
|
+
* @param kit - plugin kit.
|
|
18
|
+
* @param sessionId - harness session id.
|
|
19
|
+
* @param account - account snapshot (gives the route).
|
|
20
|
+
* @param useProjection - the slot's standard projection hook.
|
|
21
|
+
*/
|
|
22
|
+
export declare function useReportChoice(kit: Kit, sessionId: string, account: AccountSnapshot | null, useProjection: UseProjection | undefined): void;
|
|
23
|
+
/**
|
|
24
|
+
* Whether the conversation's memory lives on a model other than the one chosen.
|
|
25
|
+
* @param view - conversation view.
|
|
26
|
+
* @param choice - composer choice.
|
|
27
|
+
* @param route - this plugin's provider route.
|
|
28
|
+
* @returns true when sending now would leave the memory behind.
|
|
29
|
+
*/
|
|
30
|
+
export declare function memoryElsewhere(view: SessionView | null, choice: ModelChoice | null | undefined, route: string | undefined): boolean;
|
|
31
|
+
/**
|
|
32
|
+
* A model's display name.
|
|
33
|
+
* @param account - account snapshot.
|
|
34
|
+
* @param id - model id.
|
|
35
|
+
* @returns the name.
|
|
36
|
+
*/
|
|
37
|
+
export declare function modelLabel(account: AccountSnapshot | null, id: string): string;
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser-side state: observable snapshots fed by the Host's `adaptiq`
|
|
3
|
+
* Remote streams, plus typed calls. Components read stores through the slot
|
|
4
|
+
* framework's `use<Name>` hooks; nothing here touches React.
|
|
5
|
+
*/
|
|
6
|
+
import type { AccountSnapshot, ConversationPage, CreateKnowledgeInput, CreateKnowledgeResult, DiagnosticsView, KnowledgePage, MakeAvailableResult, Preferences, PurchaseView, SessionView, SignInStart } from '@adaptiqai/core/types';
|
|
7
|
+
/** The observable contract the slot framework binds to `use<Name>` hooks. */
|
|
8
|
+
export interface Observable<T> {
|
|
9
|
+
getSnapshot(): T;
|
|
10
|
+
subscribe(listener: () => void): () => void;
|
|
11
|
+
}
|
|
12
|
+
/** A writable observable. */
|
|
13
|
+
export interface Store<T> extends Observable<T> {
|
|
14
|
+
set(value: T): void;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* A store that starts its source with the first subscriber and stops it a
|
|
18
|
+
* little after the last one leaves (a remount does not reopen the stream).
|
|
19
|
+
* @param initial - value before the source answers.
|
|
20
|
+
* @param start - open the source; return its stop function.
|
|
21
|
+
* @returns the store.
|
|
22
|
+
*/
|
|
23
|
+
export declare function lazyStore<T>(initial: T, start?: (set: (value: T) => void) => () => void): Store<T>;
|
|
24
|
+
/** One Remote call result as the client runtime returns it. */
|
|
25
|
+
type RemoteResult<T> = {
|
|
26
|
+
readonly ok: true;
|
|
27
|
+
readonly value: T;
|
|
28
|
+
} | {
|
|
29
|
+
readonly ok: false;
|
|
30
|
+
readonly error: Error & {
|
|
31
|
+
code?: string;
|
|
32
|
+
details?: {
|
|
33
|
+
code?: string;
|
|
34
|
+
status?: number | null;
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
};
|
|
38
|
+
/** The `adaptiq` namespace as mounted on `ctx.remote`. */
|
|
39
|
+
export interface AdaptiqRemote {
|
|
40
|
+
getState(): Promise<RemoteResult<AccountSnapshot>>;
|
|
41
|
+
watch(signal?: AbortSignal): AsyncIterable<AccountSnapshot> & {
|
|
42
|
+
dispose(): void;
|
|
43
|
+
};
|
|
44
|
+
startSignIn(): Promise<RemoteResult<SignInStart>>;
|
|
45
|
+
cancelSignIn(): Promise<RemoteResult<void>>;
|
|
46
|
+
signOut(): Promise<RemoteResult<void>>;
|
|
47
|
+
refresh(): Promise<RemoteResult<AccountSnapshot>>;
|
|
48
|
+
setPreferences(patch: Partial<Preferences>): Promise<RemoteResult<Preferences>>;
|
|
49
|
+
dismissNotice(id: string): Promise<RemoteResult<void>>;
|
|
50
|
+
getSession(sessionId: string): Promise<RemoteResult<SessionView>>;
|
|
51
|
+
watchSession(sessionId: string, signal?: AbortSignal): AsyncIterable<SessionView> & {
|
|
52
|
+
dispose(): void;
|
|
53
|
+
};
|
|
54
|
+
setRemember(sessionId: string, remember: boolean): Promise<RemoteResult<SessionView>>;
|
|
55
|
+
setSessionModel(sessionId: string, model?: string, lastUsed?: string): Promise<RemoteResult<SessionView>>;
|
|
56
|
+
makeKnowledgeAvailable(id: string, from: string, sessionId?: string): Promise<RemoteResult<MakeAvailableResult>>;
|
|
57
|
+
startPurchase(offerId: string, lanes: number): Promise<RemoteResult<PurchaseView>>;
|
|
58
|
+
checkPurchase(): Promise<RemoteResult<void>>;
|
|
59
|
+
cancelPurchase(): Promise<RemoteResult<void>>;
|
|
60
|
+
dismissPurchase(): Promise<RemoteResult<void>>;
|
|
61
|
+
listConversations(sessionId: string, query?: string, cursor?: string): Promise<RemoteResult<ConversationPage>>;
|
|
62
|
+
attachConversation(sessionId: string, conversationId: string): Promise<RemoteResult<SessionView>>;
|
|
63
|
+
detachConversation(sessionId: string, conversationId: string): Promise<RemoteResult<SessionView>>;
|
|
64
|
+
listKnowledge(query?: string, cursor?: string, sessionId?: string, model?: string): Promise<RemoteResult<KnowledgePage>>;
|
|
65
|
+
attachKnowledge(sessionId: string, id: string): Promise<RemoteResult<SessionView>>;
|
|
66
|
+
detachKnowledge(sessionId: string, id: string): Promise<RemoteResult<SessionView>>;
|
|
67
|
+
createKnowledge(input: CreateKnowledgeInput): Promise<RemoteResult<CreateKnowledgeResult>>;
|
|
68
|
+
openExternal(url: string): Promise<RemoteResult<boolean>>;
|
|
69
|
+
diagnostics(): Promise<RemoteResult<DiagnosticsView>>;
|
|
70
|
+
}
|
|
71
|
+
/** The client context slice this plugin uses. */
|
|
72
|
+
export interface ClientRemote {
|
|
73
|
+
readonly adaptiq: AdaptiqRemote;
|
|
74
|
+
readonly $host?: {
|
|
75
|
+
readonly isLoopback?: boolean;
|
|
76
|
+
readonly home?: string;
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Unwrap a Remote result: the error branch becomes a thrown Error with a
|
|
81
|
+
* readable message.
|
|
82
|
+
* @param pending - the Remote call.
|
|
83
|
+
* @returns the value.
|
|
84
|
+
*/
|
|
85
|
+
export declare function unwrap<T>(pending: Promise<RemoteResult<T>>): Promise<T>;
|
|
86
|
+
/**
|
|
87
|
+
* Keep a Remote stream open: reopen it after a carrier loss with backoff.
|
|
88
|
+
* @param open - open one stream.
|
|
89
|
+
* @param onValue - receives every value.
|
|
90
|
+
* @param onDown - the stream is reconnecting.
|
|
91
|
+
* @returns stop.
|
|
92
|
+
*/
|
|
93
|
+
export declare function followStream<T>(open: () => AsyncIterable<T> & {
|
|
94
|
+
dispose(): void;
|
|
95
|
+
}, onValue: (value: T) => void, onDown?: () => void): () => void;
|
|
96
|
+
/** Shared client state for every component of the plugin. */
|
|
97
|
+
export interface ClientState {
|
|
98
|
+
readonly account: Store<AccountSnapshot | null>;
|
|
99
|
+
session(sessionId: string): Store<SessionView | null>;
|
|
100
|
+
/** The conversation whose composer was shown most recently (the Knowledge page acts on it). */
|
|
101
|
+
readonly activeSession: Store<string | null>;
|
|
102
|
+
/** Last-turn flashes: sessionId → time the pill should show "from memory" until. */
|
|
103
|
+
dispose(): void;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Create the client state over the mounted Remote.
|
|
107
|
+
* @param remote - `ctx.remote`.
|
|
108
|
+
* @param onReset - subscribe to connection resets (reopen streams).
|
|
109
|
+
* @returns the state.
|
|
110
|
+
*/
|
|
111
|
+
export declare function createClientState(remote: ClientRemote, onReset: (listener: () => void) => () => void): ClientState;
|
|
112
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const FONT_CSS: string;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/** AdaptiqAI building blocks: the cairn, the lockup, icons, meters and overlays. */
|
|
2
|
+
import { type ReactNode } from 'react';
|
|
3
|
+
import { formatTokens } from '@adaptiqai/core/format';
|
|
4
|
+
/** Translate with the plugin's dictionary. */
|
|
5
|
+
export type T = (key: string, params?: Record<string, unknown>) => string;
|
|
6
|
+
/** The cairn: three coral stones under one ink stone. */
|
|
7
|
+
export declare function Cairn({ size, alive, onDark }: {
|
|
8
|
+
size?: number;
|
|
9
|
+
alive?: boolean;
|
|
10
|
+
onDark?: boolean;
|
|
11
|
+
}): import("react").JSX.Element;
|
|
12
|
+
/** The AdaptiqAI wordmark in the current text colour. */
|
|
13
|
+
export declare function Wordmark({ height }: {
|
|
14
|
+
height?: number;
|
|
15
|
+
}): import("react").JSX.Element;
|
|
16
|
+
declare const PATHS: Record<string, ReactNode>;
|
|
17
|
+
/** A stroke icon in the Lucide geometry the Knowledge app uses. */
|
|
18
|
+
export declare function Icon({ name, size }: {
|
|
19
|
+
name: keyof typeof PATHS | string;
|
|
20
|
+
size?: number;
|
|
21
|
+
}): import("react").JSX.Element;
|
|
22
|
+
/** A progress ring. */
|
|
23
|
+
export declare function Ring({ fraction, size, stroke }: {
|
|
24
|
+
fraction: number;
|
|
25
|
+
size?: number;
|
|
26
|
+
stroke?: number;
|
|
27
|
+
}): import("react").JSX.Element;
|
|
28
|
+
/** A segmented usage bar. */
|
|
29
|
+
export declare function UsageBar({ segments, warn, thin }: {
|
|
30
|
+
segments: readonly {
|
|
31
|
+
cls: string;
|
|
32
|
+
fraction: number;
|
|
33
|
+
}[];
|
|
34
|
+
warn?: boolean;
|
|
35
|
+
thin?: boolean;
|
|
36
|
+
}): import("react").JSX.Element;
|
|
37
|
+
/** Compact token text. */
|
|
38
|
+
export declare const tokens: typeof formatTokens;
|
|
39
|
+
/** Render into document.body inside an `.aq` scope (so tokens and dark mode apply). */
|
|
40
|
+
export declare function Portal({ children, className }: {
|
|
41
|
+
children: ReactNode;
|
|
42
|
+
className: string;
|
|
43
|
+
}): import("react").ReactPortal;
|
|
44
|
+
/** A centred modal with scrim, Escape and focus handling. */
|
|
45
|
+
export declare function Modal({ onClose, children, label }: {
|
|
46
|
+
onClose: () => void;
|
|
47
|
+
children: ReactNode;
|
|
48
|
+
label: string;
|
|
49
|
+
}): import("react").JSX.Element;
|
|
50
|
+
/** Copy text and say so for a moment. */
|
|
51
|
+
export declare function useCopy(): [boolean, (text: string) => void];
|
|
52
|
+
/** Re-render every `ms` (relative times, countdowns). */
|
|
53
|
+
export declare function useTick(ms: number): number;
|
|
54
|
+
/**
|
|
55
|
+
* "just now" / "4 min ago" / a date.
|
|
56
|
+
* @param t - translate.
|
|
57
|
+
* @param at - time in ms.
|
|
58
|
+
* @param now - current time.
|
|
59
|
+
* @returns relative text.
|
|
60
|
+
*/
|
|
61
|
+
export declare function relative(t: T, at: number, now: number): string;
|
|
62
|
+
/** Run a promise-returning action with busy and error state. */
|
|
63
|
+
export declare function useAction(): {
|
|
64
|
+
busy: boolean;
|
|
65
|
+
error: string | null;
|
|
66
|
+
run: (work: () => Promise<unknown>) => Promise<boolean>;
|
|
67
|
+
clear: () => void;
|
|
68
|
+
};
|
|
69
|
+
export {};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The AdaptiqAI model provider: a harness LlmAdapter over the OpenAI-compatible
|
|
3
|
+
* AdaptiqAI API. Models, their windows, thinking levels and sampling defaults
|
|
4
|
+
* come from the workspace catalog; requests carry the harness session id so
|
|
5
|
+
* the server keeps one native memory per conversation.
|
|
6
|
+
*/
|
|
7
|
+
import { LlmAdapter, LlmError } from '@deepseek-ai/dsh-llm';
|
|
8
|
+
import type { GenerateOptions, LlmModelInfo, LlmProviderInfo, LlmResolvedModelInfo, PreparedAdapterCall, ResolvedRetryPolicy, StreamChunk } from '@deepseek-ai/dsh-llm';
|
|
9
|
+
import { type AdaptiqFailure, type AuthManager, type CatalogModel, type RequestEvents } from '@adaptiqai/core';
|
|
10
|
+
/** What the adapter tells the rest of the plugin about each request. */
|
|
11
|
+
export interface AdapterDeps {
|
|
12
|
+
readonly route: string;
|
|
13
|
+
readonly displayName: string;
|
|
14
|
+
readonly apiBase: string;
|
|
15
|
+
readonly pluginVersion: string;
|
|
16
|
+
readonly progressEvents: boolean;
|
|
17
|
+
readonly idleTimeoutMs: number;
|
|
18
|
+
readonly auth: AuthManager;
|
|
19
|
+
/** The current catalog (may be empty before the first refresh). */
|
|
20
|
+
models(): readonly CatalogModel[];
|
|
21
|
+
/** The catalog, refreshed first when empty or stale. */
|
|
22
|
+
ensureModels(signal?: AbortSignal): Promise<readonly CatalogModel[]>;
|
|
23
|
+
/** A request named a model the server no longer offers: refresh soon. */
|
|
24
|
+
modelMissing(id: string): void;
|
|
25
|
+
/** Whether new messages of this conversation are saved to memory. */
|
|
26
|
+
remember(sessionId: string | undefined): boolean;
|
|
27
|
+
/** Whether the server already stores this conversation (may look it up first). */
|
|
28
|
+
stored(sessionId: string | undefined): boolean | Promise<boolean>;
|
|
29
|
+
readonly events: RequestEvents;
|
|
30
|
+
readonly fetch?: typeof fetch;
|
|
31
|
+
}
|
|
32
|
+
/** The harness retries busy and preparing answers itself, honouring Retry-After. */
|
|
33
|
+
export declare const RETRY_POLICY: ResolvedRetryPolicy;
|
|
34
|
+
/**
|
|
35
|
+
* Exact-route model info the harness reads (context window, efforts, output default).
|
|
36
|
+
* @param route - provider route id.
|
|
37
|
+
* @param model - catalog entry.
|
|
38
|
+
* @returns the resolved info.
|
|
39
|
+
*/
|
|
40
|
+
export declare function resolvedInfo(route: string, model: CatalogModel): LlmResolvedModelInfo;
|
|
41
|
+
/** An LlmError whose code and facts the harness routes on. */
|
|
42
|
+
export declare function toLlmError(failure: AdaptiqFailure, cause?: unknown): LlmError;
|
|
43
|
+
export declare class AdaptiqAdapter extends LlmAdapter {
|
|
44
|
+
private readonly deps;
|
|
45
|
+
private readonly fetch;
|
|
46
|
+
constructor(deps: AdapterDeps);
|
|
47
|
+
providerInfo(provider: string): LlmProviderInfo;
|
|
48
|
+
providerRetryPolicy(): ResolvedRetryPolicy;
|
|
49
|
+
listModels(provider: string): Promise<readonly LlmModelInfo[]>;
|
|
50
|
+
resolveModel(provider: string, model: string, signal?: AbortSignal): Promise<LlmResolvedModelInfo>;
|
|
51
|
+
prepareCall(provider: string, model: string, signal?: AbortSignal): Promise<PreparedAdapterCall>;
|
|
52
|
+
stream(options: GenerateOptions): AsyncIterable<StreamChunk>;
|
|
53
|
+
private generate;
|
|
54
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** `/adaptiq`: status, sign-in, privacy and knowledge from the composer, in plain text. */
|
|
2
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
3
|
+
import { type AuthManager, type Workspace } from '@adaptiqai/core';
|
|
4
|
+
/**
|
|
5
|
+
* The action word of `/adaptiq …`, however the composer passes it: with or
|
|
6
|
+
* without the command name, a leading slash, or a completion glued on with "/".
|
|
7
|
+
* @param rawInput - text after (or including) the command name.
|
|
8
|
+
* @returns the action, lower case; "" for none.
|
|
9
|
+
*/
|
|
10
|
+
export declare function commandAction(rawInput: string): string;
|
|
11
|
+
/**
|
|
12
|
+
* Register `/adaptiq`.
|
|
13
|
+
* @param ctx - context with the `commands` service.
|
|
14
|
+
* @param workspace - the workspace.
|
|
15
|
+
* @param auth - the sign-in owner.
|
|
16
|
+
*/
|
|
17
|
+
export declare function registerCommand(ctx: Context, workspace: Workspace, auth: AuthManager): void;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/** Plugin configuration: everything has a production default, nothing names a model. */
|
|
2
|
+
import z from '@deepseek-ai/schemastery';
|
|
3
|
+
export interface Config {
|
|
4
|
+
/** AdaptiqAI API origin (the OpenAI-compatible API lives under `/v1`). */
|
|
5
|
+
apiBase: string;
|
|
6
|
+
/** The AdaptiqAI knowledge console. */
|
|
7
|
+
consoleUrl: string;
|
|
8
|
+
/** Provider route id the models appear under in the model picker. */
|
|
9
|
+
route: string;
|
|
10
|
+
/** Provider name in the model picker. */
|
|
11
|
+
displayName: string;
|
|
12
|
+
/** Credential reference holding an API key for headless use (`ak_live_…`). Optional when signed in. */
|
|
13
|
+
apiKeyEnv: string;
|
|
14
|
+
/** Seconds between catalog refreshes while the harness runs. */
|
|
15
|
+
catalogRefreshSeconds: number;
|
|
16
|
+
/** Seconds between account/lane/memory refreshes while someone is watching. */
|
|
17
|
+
accountRefreshSeconds: number;
|
|
18
|
+
/** Seconds a stream may stay silent before the request counts as stalled. */
|
|
19
|
+
streamIdleTimeoutSeconds: number;
|
|
20
|
+
/** Register the adaptiq_knowledge, adaptiq_memory and adaptiq_create_knowledge agent tools. */
|
|
21
|
+
tools: boolean;
|
|
22
|
+
/** Look up newer plugin versions on the npm registry (once a day). */
|
|
23
|
+
updateCheck: boolean;
|
|
24
|
+
/** Ask the server for streamed progress while a long conversation is prepared. */
|
|
25
|
+
progressEvents: boolean;
|
|
26
|
+
}
|
|
27
|
+
export declare const Config: z<Config>;
|
|
28
|
+
/**
|
|
29
|
+
* Normalise the configured API origin: no trailing slash and no `/v1`.
|
|
30
|
+
* @param value - configured origin, possibly with `/v1`.
|
|
31
|
+
* @returns the origin without a trailing `/v1`.
|
|
32
|
+
*/
|
|
33
|
+
export declare function apiOrigin(value: string): string;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `adaptiq` Remote namespace: what the browser half may ask the Host.
|
|
3
|
+
* Tokens never cross it; every method answers with plain snapshots.
|
|
4
|
+
* scripts/remote-spec.mjs lists the same methods for the Typert artifacts.
|
|
5
|
+
*/
|
|
6
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
7
|
+
import { TypertRemoteService } from '@deepseek-ai/dsh-typert-protocol';
|
|
8
|
+
import { type AccountSnapshot, type AuthManager, type CreateKnowledgeInput, type CreateKnowledgeResult, type DiagnosticsView, type KnowledgePage, type ConversationPage, type MakeAvailableResult, type Preferences, type PurchaseView, type SessionView, type SignInStart, type Workspace } from '@adaptiqai/core';
|
|
9
|
+
declare module '@deepseek-ai/dsh-typert-protocol' {
|
|
10
|
+
interface RemoteErrorDetailsMap {
|
|
11
|
+
/** An AdaptiqAI call failed; `code` is the plugin's stable failure code. */
|
|
12
|
+
'adaptiq/failed': {
|
|
13
|
+
readonly code: string;
|
|
14
|
+
readonly status: number | null;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
declare module '@deepseek-ai/cordis' {
|
|
19
|
+
interface Context {
|
|
20
|
+
adaptiqController: AdaptiqController;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/** What the controller works on. */
|
|
24
|
+
export interface ControllerDeps {
|
|
25
|
+
readonly workspace: Workspace;
|
|
26
|
+
readonly auth: AuthManager;
|
|
27
|
+
}
|
|
28
|
+
/** AdaptiqAI account, memory and knowledge for the browser half of the AdaptiqAI plugin. */
|
|
29
|
+
export declare class AdaptiqController extends TypertRemoteService {
|
|
30
|
+
private readonly deps;
|
|
31
|
+
static inject: string[];
|
|
32
|
+
constructor(ctx: Context, deps: ControllerDeps);
|
|
33
|
+
/** Read the current account snapshot. */
|
|
34
|
+
getState(): Promise<AccountSnapshot>;
|
|
35
|
+
/** Follow the account snapshot: the current one, then every change. */
|
|
36
|
+
watch(signal: AbortSignal): AsyncIterable<AccountSnapshot>;
|
|
37
|
+
/** Start a browser sign-in and return the approval link and code. */
|
|
38
|
+
startSignIn(): Promise<SignInStart>;
|
|
39
|
+
/** Stop waiting for a browser approval. */
|
|
40
|
+
cancelSignIn(): Promise<void>;
|
|
41
|
+
/** Forget the saved AdaptiqAI connection on this computer. */
|
|
42
|
+
signOut(): Promise<void>;
|
|
43
|
+
/** Re-read the workspace, its models, lanes and memory now. */
|
|
44
|
+
refresh(): Promise<AccountSnapshot>;
|
|
45
|
+
/** Change saved plugin preferences. */
|
|
46
|
+
setPreferences(patch: Partial<Preferences>): Promise<Preferences>;
|
|
47
|
+
/** Take one notice down. */
|
|
48
|
+
dismissNotice(id: string): Promise<void>;
|
|
49
|
+
/** Read one conversation's memory and knowledge. */
|
|
50
|
+
getSession(sessionIdValue: string): Promise<SessionView>;
|
|
51
|
+
/** Follow one conversation's memory and request state. */
|
|
52
|
+
watchSession(sessionIdValue: string, signal: AbortSignal): AsyncIterable<SessionView>;
|
|
53
|
+
/** Choose whether new messages in this conversation are saved to memory. */
|
|
54
|
+
setRemember(sessionIdValue: string, remember: boolean): Promise<SessionView>;
|
|
55
|
+
/** Tell the plugin which AdaptiqAI model this conversation has selected (none for another provider) and which one it last ran on. */
|
|
56
|
+
setSessionModel(sessionIdValue: string, model?: string, lastUsed?: string): Promise<SessionView>;
|
|
57
|
+
/** Search the workspace knowledge library. */
|
|
58
|
+
listKnowledge(query?: string, cursor?: string, sessionIdValue?: string, model?: string): Promise<KnowledgePage>;
|
|
59
|
+
/** Make a collection built for another model available for the model this conversation uses. */
|
|
60
|
+
makeKnowledgeAvailable(id: string, from: string, sessionIdValue?: string): Promise<MakeAvailableResult>;
|
|
61
|
+
/** Start getting lanes on a model: the person confirms (and pays) in the browser. */
|
|
62
|
+
startPurchase(offerId: string, lanes: number): Promise<PurchaseView>;
|
|
63
|
+
/** Check the purchase in progress now. */
|
|
64
|
+
checkPurchase(): Promise<void>;
|
|
65
|
+
/** Stop following the purchase in progress. */
|
|
66
|
+
cancelPurchase(): Promise<void>;
|
|
67
|
+
/** Put away a finished purchase. */
|
|
68
|
+
dismissPurchase(): Promise<void>;
|
|
69
|
+
/** Saved conversations on the model this conversation uses, newest first. */
|
|
70
|
+
listConversations(sessionIdValue: string, query?: string, cursor?: string): Promise<ConversationPage>;
|
|
71
|
+
/** Let this conversation read another one. */
|
|
72
|
+
attachConversation(sessionIdValue: string, conversationId: string): Promise<SessionView>;
|
|
73
|
+
/** Stop reading another conversation. */
|
|
74
|
+
detachConversation(sessionIdValue: string, conversationId: string): Promise<SessionView>;
|
|
75
|
+
/** Use one collection in this conversation. */
|
|
76
|
+
attachKnowledge(sessionIdValue: string, id: string): Promise<SessionView>;
|
|
77
|
+
/** Stop using one collection in this conversation. */
|
|
78
|
+
detachKnowledge(sessionIdValue: string, id: string): Promise<SessionView>;
|
|
79
|
+
/** Create a collection from files, text or links. */
|
|
80
|
+
createKnowledge(input: CreateKnowledgeInput): Promise<CreateKnowledgeResult>;
|
|
81
|
+
/** Open an AdaptiqAI page in the default browser. */
|
|
82
|
+
openExternal(url: string): Promise<boolean>;
|
|
83
|
+
/** A secret-free report of the connection and recent failures. */
|
|
84
|
+
diagnostics(): Promise<DiagnosticsView>;
|
|
85
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
2
|
+
import { Config } from './config.ts';
|
|
3
|
+
export { Config };
|
|
4
|
+
export declare const name = "adaptiq";
|
|
5
|
+
export declare const inject: string[];
|
|
6
|
+
export declare const usage = "\nAdaptiqAI models with native memory, signed in with your AdaptiqAI account.\nOpen **Settings \u2192 AdaptiqAI** to connect, or run `/adaptiq signin`.\n";
|
|
7
|
+
/**
|
|
8
|
+
* Mount the plugin.
|
|
9
|
+
* @param ctx - the plugin context.
|
|
10
|
+
* @param config - resolved configuration.
|
|
11
|
+
*/
|
|
12
|
+
export declare function apply(ctx: Context, config: Config): Promise<void>;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
2
|
+
import type { CredentialStore, StateStore } from '@adaptiqai/core';
|
|
3
|
+
/** The harness credential record holding the workspace grant. */
|
|
4
|
+
export declare const GRANT_KEY: {
|
|
5
|
+
readonly scope: "adaptiq";
|
|
6
|
+
readonly id: "workspace";
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* The grant record in `$DSH_HOME/.credentials.yaml` (0600, cross-process
|
|
10
|
+
* writer lock), plus the optional API-key reference for headless use.
|
|
11
|
+
* @param ctx - the plugin context with `credentials`.
|
|
12
|
+
* @param apiKeyEnv - credential reference name of the API key.
|
|
13
|
+
* @returns the credential store.
|
|
14
|
+
*/
|
|
15
|
+
export declare function harnessCredentialStore(ctx: Context, apiKeyEnv: string): CredentialStore;
|
|
16
|
+
/**
|
|
17
|
+
* Preferences and per-conversation memory choices in one JSON file.
|
|
18
|
+
* @param path - file path under the harness home.
|
|
19
|
+
* @returns the state store.
|
|
20
|
+
*/
|
|
21
|
+
export declare function fileStateStore(path: string): StateStore;
|
|
22
|
+
/**
|
|
23
|
+
* Open a URL in the default browser of the computer the harness runs on.
|
|
24
|
+
* @param url - an http(s) URL.
|
|
25
|
+
* @returns whether a browser process was started.
|
|
26
|
+
*/
|
|
27
|
+
export declare function openInBrowser(url: string): Promise<boolean>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Chat Completions SSE → harness stream chunks. Follows the adapter protocol:
|
|
3
|
+
* block indexes in first-seen order, raw JSON tool arguments, usage before
|
|
4
|
+
* finish, nothing after finish.
|
|
5
|
+
*/
|
|
6
|
+
import type { StreamChunk, TokenUsage } from '@deepseek-ai/dsh-llm';
|
|
7
|
+
import { type SseEvent } from '@adaptiqai/core';
|
|
8
|
+
export { mapUsage, parseSse, type SseEvent } from '@adaptiqai/core';
|
|
9
|
+
/** Hooks the translator calls as the stream unfolds. */
|
|
10
|
+
export interface TranslateHooks {
|
|
11
|
+
/** A server progress frame (`adaptiq.progress`): stage such as `context.preparing` or `inference.queued`. */
|
|
12
|
+
onProgress?(stage: string, elapsedMs: number | null): void;
|
|
13
|
+
/** The first visible output (text, thinking or a tool call) arrived. */
|
|
14
|
+
onFirstOutput?(): void;
|
|
15
|
+
/** An in-band error: map it to the thrown failure. */
|
|
16
|
+
onError(payload: Record<string, unknown>): Error;
|
|
17
|
+
onUsage?(usage: TokenUsage): void;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Translate decoded SSE events into harness stream chunks.
|
|
21
|
+
* @param events - parsed SSE events.
|
|
22
|
+
* @param hooks - progress, usage and error mapping.
|
|
23
|
+
* @returns stream chunks ending in exactly one finish chunk.
|
|
24
|
+
*/
|
|
25
|
+
export declare function translate(events: AsyncIterable<SseEvent>, hooks: TranslateHooks): AsyncGenerator<StreamChunk>;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
2
|
+
import type { Workspace } from '@adaptiqai/core';
|
|
3
|
+
/**
|
|
4
|
+
* The media type for a file name.
|
|
5
|
+
* @param name - file name.
|
|
6
|
+
* @returns a media type, `text/plain` for source code.
|
|
7
|
+
*/
|
|
8
|
+
export declare function mediaTypeOf(name: string): string;
|
|
9
|
+
/**
|
|
10
|
+
* Register the AdaptiqAI agent tools.
|
|
11
|
+
* @param ctx - context with the `tools` service.
|
|
12
|
+
* @param workspace - the workspace.
|
|
13
|
+
*/
|
|
14
|
+
export declare function registerTools(ctx: Context, workspace: Workspace): void;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Harness request → OpenAI Chat Completions body. Model-specific behaviour
|
|
3
|
+
* (thinking field and values, sampling defaults) comes only from the
|
|
4
|
+
* model's catalog entry.
|
|
5
|
+
*/
|
|
6
|
+
import type { GenerateOptions } from '@deepseek-ai/dsh-llm';
|
|
7
|
+
import { type CatalogModel } from '@adaptiqai/core';
|
|
8
|
+
/** One Chat Completions message. */
|
|
9
|
+
export type WireMessage = {
|
|
10
|
+
role: 'system';
|
|
11
|
+
content: string;
|
|
12
|
+
} | {
|
|
13
|
+
role: 'user';
|
|
14
|
+
content: string;
|
|
15
|
+
} | {
|
|
16
|
+
role: 'assistant';
|
|
17
|
+
content: string | null;
|
|
18
|
+
tool_calls?: WireToolCall[];
|
|
19
|
+
[reasoning: string]: unknown;
|
|
20
|
+
} | {
|
|
21
|
+
role: 'tool';
|
|
22
|
+
tool_call_id: string;
|
|
23
|
+
content: string;
|
|
24
|
+
};
|
|
25
|
+
export interface WireToolCall {
|
|
26
|
+
id: string;
|
|
27
|
+
type: 'function';
|
|
28
|
+
function: {
|
|
29
|
+
name: string;
|
|
30
|
+
arguments: string;
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
/** Per-request facts the adapter adds beyond the harness request. */
|
|
34
|
+
export interface WireExtras {
|
|
35
|
+
/** False when the person chose not to save new messages of this conversation. */
|
|
36
|
+
readonly remember: boolean;
|
|
37
|
+
/** True when the server already stores this conversation. */
|
|
38
|
+
readonly stored?: boolean;
|
|
39
|
+
/** Ask for streamed usage (always on for the adapter). */
|
|
40
|
+
readonly includeUsage?: boolean;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Convert the harness history to Chat Completions messages.
|
|
44
|
+
* @param options - the harness request.
|
|
45
|
+
* @returns the wire messages in order.
|
|
46
|
+
*/
|
|
47
|
+
export declare function wireMessages(options: Pick<GenerateOptions, 'messages' | 'system'>): WireMessage[];
|
|
48
|
+
/**
|
|
49
|
+
* Build the request body for one call.
|
|
50
|
+
* @param options - the harness request.
|
|
51
|
+
* @param model - the model's catalog entry, when known.
|
|
52
|
+
* @param extras - memory preference and stream options.
|
|
53
|
+
* @returns the JSON body.
|
|
54
|
+
*/
|
|
55
|
+
export declare function buildChatBody(options: GenerateOptions, model: CatalogModel | null, extras: WireExtras): Record<string, unknown>;
|
|
56
|
+
/**
|
|
57
|
+
* The session headers for one call. A title request carries none: it reuses the
|
|
58
|
+
* conversation id with a different history and must not fork the saved conversation.
|
|
59
|
+
* @param options - the harness request.
|
|
60
|
+
* @returns header name → value.
|
|
61
|
+
*/
|
|
62
|
+
export declare function sessionHeaders(options: Pick<GenerateOptions, 'sessionId' | 'purpose'>): Record<string, string>;
|
package/locale/da.json
ADDED
package/locale/en.json
ADDED