@appmind/core 0.0.0-stage → 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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 AppMind contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,11 @@
1
- # Temporary Holding Version
1
+ # @appmind/core
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ AppMind core runtime: agent orchestration, UI context, action registry, and provider interfaces.
4
+
5
+ Part of [AppMind](https://github.com/dmitripoli/appmind) — a local-first, drop-in AI copilot for web apps. See the main README for setup and concepts.
6
+
7
+ ```bash
8
+ npm install @appmind/core
9
+ ```
10
+
11
+ License: MIT
@@ -0,0 +1,40 @@
1
+ import type { AppMindContext } from "./context.js";
2
+ export type ActionRisk = "read" | "low" | "medium" | "high";
3
+ /**
4
+ * An operation the application explicitly exposes to the AI (PRD §32–34).
5
+ * The model may only ever request registered actions; it can never execute
6
+ * application code directly.
7
+ */
8
+ export interface AppMindAction<TInput = unknown, TResult = unknown> {
9
+ name: string;
10
+ description: string;
11
+ /**
12
+ * A JSON-schema-like description of the parameters. Bring your own validator
13
+ * (e.g. a zod schema exposes `.parse`); AppMind treats it as opaque here and
14
+ * only requires the shape to be describable to the model.
15
+ */
16
+ parameters?: unknown;
17
+ risk?: ActionRisk;
18
+ requiresConfirmation?: boolean;
19
+ /** Hide the action from the model when it isn't applicable to the context. */
20
+ isAvailable?: (context: AppMindContext) => boolean;
21
+ execute: (input: TInput, context: AppMindContext) => Promise<TResult>;
22
+ }
23
+ /** A validated, model-requested action awaiting execution/confirmation. */
24
+ export interface PendingAction {
25
+ name: string;
26
+ input: unknown;
27
+ risk: ActionRisk;
28
+ requiresConfirmation: boolean;
29
+ }
30
+ export declare class ActionRegistry {
31
+ private actions;
32
+ register(action: AppMindAction<any, any>): () => void;
33
+ unregister(name: string): void;
34
+ get(name: string): AppMindAction<any, any> | undefined;
35
+ /** Only the actions currently applicable to the context (PRD §37). */
36
+ available(context: AppMindContext): AppMindAction<any, any>[];
37
+ /** Confirmation policy: destructive/high-risk always confirms (PRD §34–35). */
38
+ static needsConfirmation(action: AppMindAction<any, any>): boolean;
39
+ }
40
+ //# sourceMappingURL=actions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../src/actions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAEnD,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;AAE5D;;;;GAIG;AACH,MAAM,WAAW,aAAa,CAAC,MAAM,GAAG,OAAO,EAAE,OAAO,GAAG,OAAO;IAChE,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,8EAA8E;IAC9E,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,OAAO,CAAC;IACnD,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CACvE;AAED,2EAA2E;AAC3E,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;IACf,IAAI,EAAE,UAAU,CAAC;IACjB,oBAAoB,EAAE,OAAO,CAAC;CAC/B;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,OAAO,CAA8C;IAE7D,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,MAAM,IAAI;IAUrD,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAI9B,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,SAAS;IAItD,sEAAsE;IACtE,SAAS,CAAC,OAAO,EAAE,cAAc,GAAG,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE;IAI7D,+EAA+E;IAC/E,MAAM,CAAC,iBAAiB,CAAC,MAAM,EAAE,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,OAAO;CAInE"}
@@ -0,0 +1,32 @@
1
+ export class ActionRegistry {
2
+ constructor() {
3
+ this.actions = new Map();
4
+ }
5
+ register(action) {
6
+ this.actions.set(action.name, action);
7
+ // Only remove what *this* call registered: a stale disposer (e.g. React
8
+ // StrictMode's discarded first effect, or an MCP connection torn down after
9
+ // a reconnect) must not delete a newer registration under the same name.
10
+ return () => {
11
+ if (this.actions.get(action.name) === action)
12
+ this.actions.delete(action.name);
13
+ };
14
+ }
15
+ unregister(name) {
16
+ this.actions.delete(name);
17
+ }
18
+ get(name) {
19
+ return this.actions.get(name);
20
+ }
21
+ /** Only the actions currently applicable to the context (PRD §37). */
22
+ available(context) {
23
+ return [...this.actions.values()].filter((a) => !a.isAvailable || a.isAvailable(context));
24
+ }
25
+ /** Confirmation policy: destructive/high-risk always confirms (PRD §34–35). */
26
+ static needsConfirmation(action) {
27
+ if (action.requiresConfirmation !== undefined)
28
+ return action.requiresConfirmation;
29
+ return action.risk === "high" || action.risk === "medium";
30
+ }
31
+ }
32
+ //# sourceMappingURL=actions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"actions.js","sourceRoot":"","sources":["../src/actions.ts"],"names":[],"mappings":"AAiCA,MAAM,OAAO,cAAc;IAA3B;QACU,YAAO,GAAG,IAAI,GAAG,EAAmC,CAAC;IA8B/D,CAAC;IA5BC,QAAQ,CAAC,MAA+B;QACtC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACtC,wEAAwE;QACxE,4EAA4E;QAC5E,yEAAyE;QACzE,OAAO,GAAG,EAAE;YACV,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,MAAM;gBAAE,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACjF,CAAC,CAAC;IACJ,CAAC;IAED,UAAU,CAAC,IAAY;QACrB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IAED,GAAG,CAAC,IAAY;QACd,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAChC,CAAC;IAED,sEAAsE;IACtE,SAAS,CAAC,OAAuB;QAC/B,OAAO,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC;IAC5F,CAAC;IAED,+EAA+E;IAC/E,MAAM,CAAC,iBAAiB,CAAC,MAA+B;QACtD,IAAI,MAAM,CAAC,oBAAoB,KAAK,SAAS;YAAE,OAAO,MAAM,CAAC,oBAAoB,CAAC;QAClF,OAAO,MAAM,CAAC,IAAI,KAAK,MAAM,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ,CAAC;IAC5D,CAAC;CACF"}
@@ -0,0 +1,109 @@
1
+ import { type Embedder, type KnowledgeIndex, type RetrievalResult, type RetrievalWeights } from "@appmind/knowledge";
2
+ import { type AppMindAction, type PendingAction } from "./actions.js";
3
+ import { type AppMindContext } from "./context.js";
4
+ import { type AppMindEvents, type EventName } from "./events.js";
5
+ import type { AppMindModelProvider, ChatMessage, ModelLocation } from "./model.js";
6
+ import { type AppMindStorage } from "./storage.js";
7
+ import { type PromptBudget } from "./runtime.js";
8
+ export interface AppMindConfig {
9
+ knowledge: {
10
+ manifest: string;
11
+ index?: never;
12
+ } | {
13
+ index: KnowledgeIndex;
14
+ manifest?: never;
15
+ };
16
+ model?: AppMindModelProvider;
17
+ storage?: AppMindStorage;
18
+ /**
19
+ * Query embedder. If omitted, one is derived from the loaded manifest's
20
+ * `embeddingModel` so the runtime query vectors automatically match the index.
21
+ */
22
+ embedder?: Embedder;
23
+ retrieval?: {
24
+ topK?: number;
25
+ weights?: Partial<RetrievalWeights>;
26
+ };
27
+ /** Prompt token budget (defaults target a ~4K-token prompt) and optional `countTokens`. */
28
+ prompt?: Partial<PromptBudget>;
29
+ /**
30
+ * Called before executing an action that requires confirmation (PRD §35).
31
+ * Must resolve true to proceed. If omitted, confirmation-required actions are
32
+ * denied by default (fail closed).
33
+ */
34
+ onConfirm?: (pending: PendingAction) => Promise<boolean>;
35
+ /** How to fetch remote resources (manifest/index). Defaults to global fetch. */
36
+ fetch?: typeof fetch;
37
+ }
38
+ /** High-level events streamed from a chat turn. */
39
+ export type ChatEvent = {
40
+ type: "sources";
41
+ sources: RetrievalResult[];
42
+ } | {
43
+ type: "text";
44
+ delta: string;
45
+ } | {
46
+ type: "action_pending";
47
+ action: PendingAction;
48
+ } | {
49
+ type: "action_result";
50
+ name: string;
51
+ ok: boolean;
52
+ result?: unknown;
53
+ error?: string;
54
+ } | {
55
+ type: "location";
56
+ location: ModelLocation;
57
+ } | {
58
+ type: "done";
59
+ } | {
60
+ type: "error";
61
+ error: string;
62
+ };
63
+ export interface ChatOptions {
64
+ history?: ChatMessage[];
65
+ signal?: AbortSignal;
66
+ }
67
+ export declare class AppMind {
68
+ private readonly config;
69
+ private readonly ctx;
70
+ private readonly registry;
71
+ private readonly emitter;
72
+ private readonly storage;
73
+ private readonly fetchFn;
74
+ private index;
75
+ private embedder;
76
+ private started;
77
+ private confirmHandler;
78
+ constructor(config: AppMindConfig);
79
+ /**
80
+ * Set/replace the confirmation handler at runtime. The React provider uses
81
+ * this to drive its confirmation UI. Returns a disposer that restores the
82
+ * previous handler.
83
+ */
84
+ setConfirmationHandler(handler: (pending: PendingAction) => Promise<boolean>): () => void;
85
+ /** Load the knowledge index (from cache or CDN) and initialize the model. */
86
+ start(): Promise<void>;
87
+ setContext(context: AppMindContext): void;
88
+ mergeContext(patch: Partial<AppMindContext>): void;
89
+ getContext(): AppMindContext;
90
+ registerAction<TInput, TResult>(action: AppMindAction<TInput, TResult>): () => void;
91
+ search(query: string, options?: {
92
+ limit?: number;
93
+ }): Promise<RetrievalResult[]>;
94
+ chat(message: string, options?: ChatOptions): AsyncIterable<ChatEvent>;
95
+ /**
96
+ * One follow-up generation that answers the user from an action's result.
97
+ * No tools are offered (and any tool call is ignored), so it can't loop. The
98
+ * result goes in as a plain user-role message — portable across providers
99
+ * that lack native tool-result messages.
100
+ */
101
+ private answerFromResult;
102
+ private runAction;
103
+ /** Which engine the next chat turn will use (PRD §54 privacy API). */
104
+ modelLocation(): ModelLocation | undefined;
105
+ on<K extends EventName>(name: K, handler: (payload: AppMindEvents[K]) => void): () => void;
106
+ dispose(): Promise<void>;
107
+ private loadIndex;
108
+ }
109
+ //# sourceMappingURL=appmind.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"appmind.d.ts","sourceRoot":"","sources":["../src/appmind.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,306 @@
1
+ import { assertEmbedderCompatible, createEmbedder, CURRENT_INDEX_SCHEMA, retrieve, } from "@appmind/knowledge";
2
+ import { ActionRegistry } from "./actions.js";
3
+ import { ContextStore } from "./context.js";
4
+ import { Emitter } from "./events.js";
5
+ import { MemoryStorage } from "./storage.js";
6
+ import { buildSystemPrompt, DEFAULT_PROMPT_BUDGET, estimateTokens, parseToolCallFromText, toToolSpecs, windowHistory, } from "./runtime.js";
7
+ export class AppMind {
8
+ constructor(config) {
9
+ this.ctx = new ContextStore();
10
+ this.registry = new ActionRegistry();
11
+ this.emitter = new Emitter();
12
+ this.started = false;
13
+ this.config = config;
14
+ this.storage = config.storage ?? new MemoryStorage();
15
+ // Wrap (don't reference) the global fetch: a bare `globalThis.fetch` called
16
+ // as a method throws "Illegal invocation" because it loses its Window `this`.
17
+ this.fetchFn = config.fetch ?? ((input, init) => globalThis.fetch(input, init));
18
+ this.confirmHandler = config.onConfirm;
19
+ }
20
+ /**
21
+ * Set/replace the confirmation handler at runtime. The React provider uses
22
+ * this to drive its confirmation UI. Returns a disposer that restores the
23
+ * previous handler.
24
+ */
25
+ setConfirmationHandler(handler) {
26
+ const prev = this.confirmHandler;
27
+ this.confirmHandler = handler;
28
+ return () => {
29
+ this.confirmHandler = prev;
30
+ };
31
+ }
32
+ /** Load the knowledge index (from cache or CDN) and initialize the model. */
33
+ async start() {
34
+ if (this.started)
35
+ return;
36
+ this.index = await this.loadIndex();
37
+ // Guard against an index format this runtime can't read (PRD §25).
38
+ const schema = this.index.manifest.schemaVersion ?? 1;
39
+ if (schema > CURRENT_INDEX_SCHEMA) {
40
+ throw new Error(`AppMind index schema v${schema} is newer than this runtime supports (v${CURRENT_INDEX_SCHEMA}). Upgrade @appmind/core.`);
41
+ }
42
+ // Derive the query embedder from the manifest unless the app supplied one,
43
+ // guaranteeing the query vector space matches the index's document vectors.
44
+ this.embedder =
45
+ this.config.embedder ??
46
+ createEmbedder({
47
+ id: this.index.manifest.embeddingModel,
48
+ dimensions: this.index.manifest.dimensions,
49
+ });
50
+ // Fail closed if a supplied embedder doesn't match the index's vector space.
51
+ assertEmbedderCompatible(this.index.manifest, this.embedder);
52
+ if (this.config.model) {
53
+ this.emitter.emit("model_loading", { provider: this.config.model.id });
54
+ await this.config.model.initialize();
55
+ this.emitter.emit("model_ready", {
56
+ provider: this.config.model.id,
57
+ location: this.config.model.location(),
58
+ });
59
+ }
60
+ this.started = true;
61
+ this.emitter.emit("initialized", undefined);
62
+ }
63
+ // --- Context (PRD §29) ---
64
+ setContext(context) {
65
+ this.ctx.set(context);
66
+ }
67
+ mergeContext(patch) {
68
+ this.ctx.merge(patch);
69
+ }
70
+ getContext() {
71
+ return this.ctx.get();
72
+ }
73
+ // --- Actions (PRD §32) ---
74
+ registerAction(action) {
75
+ return this.registry.register(action);
76
+ }
77
+ // --- Knowledge search (PRD §28) ---
78
+ async search(query, options = {}) {
79
+ if (!this.index || !this.embedder)
80
+ throw new Error("AppMind not started: call start() first.");
81
+ const started = now();
82
+ const queryEmbedding = await this.embedder.embed(query);
83
+ const results = retrieve(queryEmbedding, query, this.index.chunks, {
84
+ limit: options.limit ?? this.config.retrieval?.topK ?? 5,
85
+ weights: this.config.retrieval?.weights,
86
+ context: {
87
+ route: this.ctx.get().route,
88
+ resourceType: this.ctx.get().resource?.type,
89
+ keywords: this.ctx.keywords(),
90
+ },
91
+ });
92
+ this.emitter.emit("retrieval", { count: results.length, latencyMs: now() - started });
93
+ return results;
94
+ }
95
+ // --- Chat / agent runtime (PRD §39) ---
96
+ async *chat(message, options = {}) {
97
+ if (!this.config.model) {
98
+ yield { type: "error", error: "No model provider configured." };
99
+ return;
100
+ }
101
+ if (!this.index) {
102
+ yield { type: "error", error: "AppMind not started: call start() first." };
103
+ return;
104
+ }
105
+ this.emitter.emit("query", { text: message });
106
+ // 1. Retrieve relevant knowledge + expose only applicable actions.
107
+ const sources = await this.search(message, {
108
+ limit: this.config.retrieval?.topK ?? 5,
109
+ });
110
+ yield { type: "sources", sources };
111
+ const actions = this.registry.available(this.ctx.get());
112
+ // Budget the prompt: window history, then fill knowledge with the remainder.
113
+ const budget = { ...DEFAULT_PROMPT_BUDGET, ...this.config.prompt };
114
+ const count = budget.countTokens ?? estimateTokens;
115
+ const history = windowHistory(options.history ?? [], budget.maxHistoryTurns);
116
+ const usedTokens = count(message) + history.reduce((s, m) => s + count(m.content), 0);
117
+ const system = buildSystemPrompt(this.ctx.toPromptBlock(), sources, actions, {
118
+ budget: this.config.prompt,
119
+ usedTokens,
120
+ });
121
+ const model = this.config.model;
122
+ yield { type: "location", location: model.location() };
123
+ this.emitter.emit("generation", { location: model.location() });
124
+ // 2. Generate. Accumulate text to detect text-encoded tool calls.
125
+ let fullText = "";
126
+ let structuredTool;
127
+ try {
128
+ for await (const ev of model.generate({
129
+ system,
130
+ messages: [...history, { role: "user", content: message }],
131
+ tools: toToolSpecs(actions),
132
+ signal: options.signal,
133
+ })) {
134
+ if (ev.type === "text") {
135
+ fullText += ev.delta;
136
+ yield { type: "text", delta: ev.delta };
137
+ }
138
+ else if (ev.type === "tool_call") {
139
+ structuredTool = { name: ev.name, arguments: ev.arguments };
140
+ }
141
+ else if (ev.type === "error") {
142
+ this.emitter.emit("error", { error: ev.error });
143
+ yield { type: "error", error: ev.error };
144
+ return;
145
+ }
146
+ }
147
+ }
148
+ catch (err) {
149
+ const error = err instanceof Error ? err.message : String(err);
150
+ this.emitter.emit("error", { error });
151
+ yield { type: "error", error };
152
+ return;
153
+ }
154
+ // 3. Resolve a tool call. A structured tool_call is trusted; a tool call
155
+ // merely parsed out of the text is honored ONLY when it names a real
156
+ // registered action — otherwise it's a hallucination and we keep the
157
+ // model's text as the answer.
158
+ let toolCall = structuredTool;
159
+ if (!toolCall) {
160
+ const parsed = parseToolCallFromText(fullText);
161
+ if (parsed && this.registry.get(parsed.name))
162
+ toolCall = parsed;
163
+ }
164
+ if (toolCall) {
165
+ let result;
166
+ for await (const ev of this.runAction(toolCall.name, toolCall.arguments)) {
167
+ if (ev.type === "action_result")
168
+ result = ev;
169
+ yield ev;
170
+ }
171
+ // 4. Hand a successful result back to the model for one answer turn, so
172
+ // "what's the ARV?" ends with the number, not just "✓ completed".
173
+ if (result?.ok) {
174
+ yield* this.answerFromResult(model, system, [...history, { role: "user", content: message }], toolCall, result.result, options.signal);
175
+ }
176
+ }
177
+ yield { type: "done" };
178
+ }
179
+ /**
180
+ * One follow-up generation that answers the user from an action's result.
181
+ * No tools are offered (and any tool call is ignored), so it can't loop. The
182
+ * result goes in as a plain user-role message — portable across providers
183
+ * that lack native tool-result messages.
184
+ */
185
+ async *answerFromResult(model, system, messages, call, result, signal) {
186
+ const serialized = truncate(typeof result === "string" ? result : JSON.stringify(result ?? null), MAX_RESULT_CHARS);
187
+ let first = true;
188
+ try {
189
+ for await (const ev of model.generate({
190
+ system,
191
+ messages: [
192
+ ...messages,
193
+ { role: "assistant", content: `Called ${call.name} with ${JSON.stringify(call.arguments ?? {})}.` },
194
+ {
195
+ role: "user",
196
+ content: `Result of ${call.name}:\n${serialized}\n\n` +
197
+ "Answer my previous question using this result. Do not call any action.",
198
+ },
199
+ ],
200
+ tools: [],
201
+ signal,
202
+ })) {
203
+ if (ev.type === "text") {
204
+ yield { type: "text", delta: first ? `\n\n${ev.delta.trimStart()}` : ev.delta };
205
+ first = false;
206
+ }
207
+ else if (ev.type === "error") {
208
+ this.emitter.emit("error", { error: ev.error });
209
+ return; // the action already succeeded; a missing summary isn't fatal
210
+ }
211
+ }
212
+ }
213
+ catch (err) {
214
+ this.emitter.emit("error", { error: err instanceof Error ? err.message : String(err) });
215
+ }
216
+ }
217
+ async *runAction(name, input) {
218
+ const action = this.registry.get(name);
219
+ if (!action) {
220
+ // Hallucinated action — reject silently at the model, surface to app (PRD §65).
221
+ yield { type: "action_result", name, ok: false, error: `Unknown action: ${name}` };
222
+ return;
223
+ }
224
+ if (action.isAvailable && !action.isAvailable(this.ctx.get())) {
225
+ yield { type: "action_result", name, ok: false, error: "Action not available in context." };
226
+ return;
227
+ }
228
+ const pending = {
229
+ name,
230
+ input,
231
+ risk: action.risk ?? "low",
232
+ requiresConfirmation: ActionRegistry.needsConfirmation(action),
233
+ };
234
+ this.emitter.emit("action_proposed", { name });
235
+ if (pending.requiresConfirmation) {
236
+ yield { type: "action_pending", action: pending };
237
+ const approved = this.confirmHandler ? await this.confirmHandler(pending) : false;
238
+ if (!approved) {
239
+ yield { type: "action_result", name, ok: false, error: "Not confirmed." };
240
+ return;
241
+ }
242
+ this.emitter.emit("action_confirmed", { name });
243
+ }
244
+ try {
245
+ const result = await action.execute(input, this.ctx.get());
246
+ this.emitter.emit("action_executed", { name, ok: true });
247
+ yield { type: "action_result", name, ok: true, result };
248
+ }
249
+ catch (err) {
250
+ const error = err instanceof Error ? err.message : String(err);
251
+ this.emitter.emit("action_executed", { name, ok: false });
252
+ yield { type: "action_result", name, ok: false, error };
253
+ }
254
+ }
255
+ /** Which engine the next chat turn will use (PRD §54 privacy API). */
256
+ modelLocation() {
257
+ return this.config.model?.location();
258
+ }
259
+ on(name, handler) {
260
+ return this.emitter.on(name, handler);
261
+ }
262
+ async dispose() {
263
+ await this.config.model?.dispose();
264
+ this.started = false;
265
+ }
266
+ // --- internals ---
267
+ async loadIndex() {
268
+ if ("index" in this.config.knowledge && this.config.knowledge.index) {
269
+ const idx = this.config.knowledge.index;
270
+ await this.storage.putIndex(idx);
271
+ return idx;
272
+ }
273
+ const manifestUrl = this.config.knowledge.manifest;
274
+ const manifest = (await (await this.fetchFn(manifestUrl)).json());
275
+ const stored = await this.storage.getStoredVersion();
276
+ if (stored === manifest.version) {
277
+ const cached = await this.storage.getIndex(manifest.version);
278
+ if (cached)
279
+ return cached;
280
+ }
281
+ // Resolve the index path relative to the manifest URL.
282
+ const indexUrl = new URL(manifest.index, toAbsolute(manifestUrl)).toString();
283
+ const chunks = (await (await this.fetchFn(indexUrl)).json());
284
+ const index = { manifest, chunks };
285
+ // Compatibility guard: build-time and runtime embedders must match (PRD §25).
286
+ // The built-in embedder is keyed by dimensions; a real embedder should also
287
+ // compare manifest.embeddingModel against the runtime model id.
288
+ await this.storage.putIndex(index);
289
+ return index;
290
+ }
291
+ }
292
+ function toAbsolute(url) {
293
+ if (/^https?:\/\//.test(url))
294
+ return url;
295
+ const base = typeof location !== "undefined" ? location.href : "http://localhost/";
296
+ return new URL(url, base).toString();
297
+ }
298
+ function now() {
299
+ return typeof performance !== "undefined" ? performance.now() : Date.now();
300
+ }
301
+ /** Cap on an action result fed back to the model (keeps the follow-up prompt small). */
302
+ const MAX_RESULT_CHARS = 4000;
303
+ function truncate(s, max) {
304
+ return s.length > max ? `${s.slice(0, max)}… [truncated]` : s;
305
+ }
306
+ //# sourceMappingURL=appmind.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"appmind.js","sourceRoot":"","sources":["../src/appmind.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Structured, app-provided description of what the user currently sees (PRD §29–31).
3
+ * AppMind never scrapes the DOM by default — the app pushes semantic state here.
4
+ */
5
+ export interface AppMindContext {
6
+ route?: string;
7
+ page?: {
8
+ type?: string;
9
+ title?: string;
10
+ };
11
+ resource?: {
12
+ type?: string;
13
+ id?: string;
14
+ name?: string;
15
+ };
16
+ /** Arbitrary visible field values / form state for the current view. */
17
+ visibleState?: Record<string, unknown>;
18
+ /** Coarse global scope: org, plan, permissions, feature flags. */
19
+ global?: Record<string, unknown>;
20
+ /** Frontend permission hints — NOT authoritative (PRD §36). */
21
+ permissions?: string[];
22
+ }
23
+ /** Holds the current context and notifies listeners on change. */
24
+ export declare class ContextStore {
25
+ private context;
26
+ private listeners;
27
+ get(): AppMindContext;
28
+ set(next: AppMindContext): void;
29
+ merge(patch: Partial<AppMindContext>): void;
30
+ subscribe(listener: (ctx: AppMindContext) => void): () => void;
31
+ /** Derive lightweight keyword signals from the context for retrieval biasing. */
32
+ keywords(): string[];
33
+ /** Human-readable block for the model prompt (PRD §40). */
34
+ toPromptBlock(): string;
35
+ }
36
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE;QACL,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,QAAQ,CAAC,EAAE;QACT,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,EAAE,CAAC,EAAE,MAAM,CAAC;QACZ,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;IACF,wEAAwE;IACxE,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvC,kEAAkE;IAClE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,+DAA+D;IAC/D,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,kEAAkE;AAClE,qBAAa,YAAY;IACvB,OAAO,CAAC,OAAO,CAAsB;IACrC,OAAO,CAAC,SAAS,CAA4C;IAE7D,GAAG,IAAI,cAAc;IAIrB,GAAG,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI;IAK/B,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,IAAI;IAI3C,SAAS,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,IAAI,GAAG,MAAM,IAAI;IAK9D,iFAAiF;IACjF,QAAQ,IAAI,MAAM,EAAE;IAoBpB,2DAA2D;IAC3D,aAAa,IAAI,MAAM;CAkCxB"}
@@ -0,0 +1,91 @@
1
+ /** Holds the current context and notifies listeners on change. */
2
+ export class ContextStore {
3
+ constructor() {
4
+ this.context = {};
5
+ this.listeners = new Set();
6
+ }
7
+ get() {
8
+ return this.context;
9
+ }
10
+ set(next) {
11
+ this.context = next;
12
+ for (const l of this.listeners)
13
+ l(next);
14
+ }
15
+ merge(patch) {
16
+ this.set({ ...this.context, ...patch });
17
+ }
18
+ subscribe(listener) {
19
+ this.listeners.add(listener);
20
+ return () => this.listeners.delete(listener);
21
+ }
22
+ /** Derive lightweight keyword signals from the context for retrieval biasing. */
23
+ keywords() {
24
+ const c = this.context;
25
+ const words = [];
26
+ if (c.route)
27
+ words.push(...c.route.split(/[/\-_]/));
28
+ if (c.page?.title)
29
+ words.push(...c.page.title.split(/\s+/));
30
+ if (c.page?.type)
31
+ words.push(c.page.type);
32
+ if (c.resource?.name)
33
+ words.push(...c.resource.name.split(/\s+/));
34
+ if (c.resource?.type)
35
+ words.push(c.resource.type);
36
+ if (c.resource?.id)
37
+ words.push(c.resource.id);
38
+ for (const bag of [c.visibleState, c.global]) {
39
+ if (!bag)
40
+ continue;
41
+ for (const [k, v] of Object.entries(bag)) {
42
+ words.push(k);
43
+ if (typeof v === "string")
44
+ words.push(v);
45
+ }
46
+ }
47
+ if (c.permissions)
48
+ words.push(...c.permissions);
49
+ return words.map((w) => w.toLowerCase()).filter((w) => w.length > 1);
50
+ }
51
+ /** Human-readable block for the model prompt (PRD §40). */
52
+ toPromptBlock() {
53
+ const c = this.context;
54
+ const lines = ["APPLICATION CONTEXT"];
55
+ if (c.route)
56
+ lines.push(`Route: ${c.route}`);
57
+ if (c.page?.title || c.page?.type) {
58
+ lines.push(`Page: ${c.page.title ?? c.page.type}`);
59
+ }
60
+ if (c.resource) {
61
+ // Always surface the id when there is one: actions/tools usually need it,
62
+ // and a display name alone leaves the model guessing (it passes the name).
63
+ const meta = [c.resource.type, c.resource.id && `id: ${c.resource.id}`].filter(Boolean);
64
+ lines.push(`Resource: ${c.resource.name ?? c.resource.id ?? ""}${meta.length ? ` (${meta.join(", ")})` : ""}`);
65
+ }
66
+ if (c.visibleState && Object.keys(c.visibleState).length > 0) {
67
+ lines.push("Visible state:");
68
+ for (const [k, v] of Object.entries(c.visibleState)) {
69
+ lines.push(` ${k}: ${formatValue(v)}`);
70
+ }
71
+ }
72
+ if (c.global && Object.keys(c.global).length > 0) {
73
+ lines.push("Global:");
74
+ for (const [k, v] of Object.entries(c.global)) {
75
+ lines.push(` ${k}: ${formatValue(v)}`);
76
+ }
77
+ }
78
+ if (c.permissions && c.permissions.length > 0) {
79
+ lines.push(`Permissions: ${c.permissions.join(", ")}`);
80
+ }
81
+ return lines.join("\n");
82
+ }
83
+ }
84
+ function formatValue(v) {
85
+ if (v === null || v === undefined)
86
+ return "—";
87
+ if (typeof v === "object")
88
+ return JSON.stringify(v);
89
+ return String(v);
90
+ }
91
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ /** Optional telemetry/lifecycle events (PRD §55). */
2
+ export interface AppMindEvents {
3
+ initialized: void;
4
+ model_loading: {
5
+ provider: string;
6
+ };
7
+ model_ready: {
8
+ provider: string;
9
+ location: "local" | "remote";
10
+ };
11
+ query: {
12
+ text: string;
13
+ };
14
+ retrieval: {
15
+ count: number;
16
+ latencyMs: number;
17
+ };
18
+ generation: {
19
+ location: "local" | "remote";
20
+ };
21
+ action_proposed: {
22
+ name: string;
23
+ };
24
+ action_confirmed: {
25
+ name: string;
26
+ };
27
+ action_executed: {
28
+ name: string;
29
+ ok: boolean;
30
+ };
31
+ error: {
32
+ error: string;
33
+ };
34
+ }
35
+ export type EventName = keyof AppMindEvents;
36
+ export declare class Emitter {
37
+ private handlers;
38
+ on<K extends EventName>(name: K, handler: (payload: AppMindEvents[K]) => void): () => void;
39
+ emit<K extends EventName>(name: K, payload: AppMindEvents[K]): void;
40
+ }
41
+ //# sourceMappingURL=events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,IAAI,CAAC;IAClB,aAAa,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IACpC,WAAW,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,OAAO,GAAG,QAAQ,CAAA;KAAE,CAAC;IAChE,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACxB,SAAS,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IAChD,UAAU,EAAE;QAAE,QAAQ,EAAE,OAAO,GAAG,QAAQ,CAAA;KAAE,CAAC;IAC7C,eAAe,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAClC,gBAAgB,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACnC,eAAe,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,OAAO,CAAA;KAAE,CAAC;IAC/C,KAAK,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;CAC1B;AAED,MAAM,MAAM,SAAS,GAAG,MAAM,aAAa,CAAC;AAE5C,qBAAa,OAAO;IAClB,OAAO,CAAC,QAAQ,CAAqD;IAErE,EAAE,CAAC,CAAC,SAAS,SAAS,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,MAAM,IAAI;IAU1F,IAAI,CAAC,CAAC,SAAS,SAAS,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,IAAI;CAWpE"}
package/dist/events.js ADDED
@@ -0,0 +1,28 @@
1
+ export class Emitter {
2
+ constructor() {
3
+ this.handlers = new Map();
4
+ }
5
+ on(name, handler) {
6
+ let set = this.handlers.get(name);
7
+ if (!set) {
8
+ set = new Set();
9
+ this.handlers.set(name, set);
10
+ }
11
+ set.add(handler);
12
+ return () => set.delete(handler);
13
+ }
14
+ emit(name, payload) {
15
+ const set = this.handlers.get(name);
16
+ if (!set)
17
+ return;
18
+ for (const h of set) {
19
+ try {
20
+ h(payload);
21
+ }
22
+ catch {
23
+ /* listener errors must not break the runtime */
24
+ }
25
+ }
26
+ }
27
+ }
28
+ //# sourceMappingURL=events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.js","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"AAgBA,MAAM,OAAO,OAAO;IAApB;QACU,aAAQ,GAAG,IAAI,GAAG,EAA0C,CAAC;IAuBvE,CAAC;IArBC,EAAE,CAAsB,IAAO,EAAE,OAA4C;QAC3E,IAAI,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAClC,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,GAAG,GAAG,IAAI,GAAG,EAAE,CAAC;YAChB,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QAC/B,CAAC;QACD,GAAG,CAAC,GAAG,CAAC,OAAiC,CAAC,CAAC;QAC3C,OAAO,GAAG,EAAE,CAAC,GAAI,CAAC,MAAM,CAAC,OAAiC,CAAC,CAAC;IAC9D,CAAC;IAED,IAAI,CAAsB,IAAO,EAAE,OAAyB;QAC1D,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACpC,IAAI,CAAC,GAAG;YAAE,OAAO;QACjB,KAAK,MAAM,CAAC,IAAI,GAAG,EAAE,CAAC;YACpB,IAAI,CAAC;gBACH,CAAC,CAAC,OAAO,CAAC,CAAC;YACb,CAAC;YAAC,MAAM,CAAC;gBACP,gDAAgD;YAClD,CAAC;QACH,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,12 @@
1
+ export { AppMind } from "./appmind.js";
2
+ export type { AppMindConfig, ChatEvent, ChatOptions } from "./appmind.js";
3
+ export type { AppMindContext } from "./context.js";
4
+ export { ContextStore } from "./context.js";
5
+ export { ActionRegistry, type AppMindAction, type ActionRisk, type PendingAction, } from "./actions.js";
6
+ export type { AppMindModelProvider, ChatMessage, GenerationEvent, GenerationRequest, ModelLocation, ToolSpec, } from "./model.js";
7
+ export { MemoryStorage, type AppMindStorage } from "./storage.js";
8
+ export type { AppMindEvents, EventName } from "./events.js";
9
+ export { buildSystemPrompt, parseToolCallFromText, estimateTokens, windowHistory, DEFAULT_PROMPT_BUDGET, type PromptBudget, type TokenCounter, } from "./runtime.js";
10
+ export type { KnowledgeChunk, KnowledgeIndex, KnowledgeManifest, RetrievalResult, Embedder, EmbedderSpec, } from "@appmind/knowledge";
11
+ export { createEmbedder, createDefaultEmbedder, assertEmbedderCompatible, embedText, PlaceholderEmbedder, TransformersEmbedder, PLACEHOLDER_EMBEDDER_ID, CURRENT_INDEX_SCHEMA, } from "@appmind/knowledge";
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC1E,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EACL,cAAc,EACd,KAAK,aAAa,EAClB,KAAK,UAAU,EACf,KAAK,aAAa,GACnB,MAAM,cAAc,CAAC;AACtB,YAAY,EACV,oBAAoB,EACpB,WAAW,EACX,eAAe,EACf,iBAAiB,EACjB,aAAa,EACb,QAAQ,GACT,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,aAAa,EAAE,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;AAClE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,cAAc,EACd,aAAa,EACb,qBAAqB,EACrB,KAAK,YAAY,EACjB,KAAK,YAAY,GAClB,MAAM,cAAc,CAAC;AAGtB,YAAY,EACV,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,eAAe,EACf,QAAQ,EACR,YAAY,GACb,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,cAAc,EACd,qBAAqB,EACrB,wBAAwB,EACxB,SAAS,EACT,mBAAmB,EACnB,oBAAoB,EACpB,uBAAuB,EACvB,oBAAoB,GACrB,MAAM,oBAAoB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,7 @@
1
+ export { AppMind } from "./appmind.js";
2
+ export { ContextStore } from "./context.js";
3
+ export { ActionRegistry, } from "./actions.js";
4
+ export { MemoryStorage } from "./storage.js";
5
+ export { buildSystemPrompt, parseToolCallFromText, estimateTokens, windowHistory, DEFAULT_PROMPT_BUDGET, } from "./runtime.js";
6
+ export { createEmbedder, createDefaultEmbedder, assertEmbedderCompatible, embedText, PlaceholderEmbedder, TransformersEmbedder, PLACEHOLDER_EMBEDDER_ID, CURRENT_INDEX_SCHEMA, } from "@appmind/knowledge";
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAGvC,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EACL,cAAc,GAIf,MAAM,cAAc,CAAC;AAStB,OAAO,EAAE,aAAa,EAAuB,MAAM,cAAc,CAAC;AAElE,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,cAAc,EACd,aAAa,EACb,qBAAqB,GAGtB,MAAM,cAAc,CAAC;AAWtB,OAAO,EACL,cAAc,EACd,qBAAqB,EACrB,wBAAwB,EACxB,SAAS,EACT,mBAAmB,EACnB,oBAAoB,EACpB,uBAAuB,EACvB,oBAAoB,GACrB,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,44 @@
1
+ /** Model provider interface (PRD §17). Implementations live in @appmind/model. */
2
+ export interface ChatMessage {
3
+ role: "system" | "user" | "assistant";
4
+ content: string;
5
+ }
6
+ /** A tool/action description handed to the model. */
7
+ export interface ToolSpec {
8
+ name: string;
9
+ description: string;
10
+ parameters?: unknown;
11
+ }
12
+ export interface GenerationRequest {
13
+ messages: ChatMessage[];
14
+ tools?: ToolSpec[];
15
+ /** Rendered application-context + knowledge block for the system prompt. */
16
+ system?: string;
17
+ signal?: AbortSignal;
18
+ }
19
+ export type GenerationEvent = {
20
+ type: "text";
21
+ delta: string;
22
+ } | {
23
+ type: "tool_call";
24
+ name: string;
25
+ arguments: unknown;
26
+ } | {
27
+ type: "error";
28
+ error: string;
29
+ } | {
30
+ type: "done";
31
+ };
32
+ /** Where a given generation actually ran — surfaced to the app (PRD §54). */
33
+ export type ModelLocation = "local" | "remote";
34
+ export interface AppMindModelProvider {
35
+ /** Human-readable id, e.g. "remote:anthropic" or "local:webllm". */
36
+ readonly id: string;
37
+ initialize(): Promise<void>;
38
+ /** Where this provider runs inference, once initialized. */
39
+ location(): ModelLocation;
40
+ supportsTools(): boolean;
41
+ generate(request: GenerationRequest): AsyncIterable<GenerationEvent>;
42
+ dispose(): Promise<void>;
43
+ }
44
+ //# sourceMappingURL=model.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"AAAA,kFAAkF;AAElF,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,WAAW,CAAC;IACtC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,qDAAqD;AACrD,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAC;IACnB,4EAA4E;IAC5E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,MAAM,MAAM,eAAe,GACvB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC/B;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,GACvD;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAChC;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAErB,6EAA6E;AAC7E,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,QAAQ,CAAC;AAE/C,MAAM,WAAW,oBAAoB;IACnC,oEAAoE;IACpE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,4DAA4D;IAC5D,QAAQ,IAAI,aAAa,CAAC;IAC1B,aAAa,IAAI,OAAO,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,iBAAiB,GAAG,aAAa,CAAC,eAAe,CAAC,CAAC;IACrE,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B"}
package/dist/model.js ADDED
@@ -0,0 +1,3 @@
1
+ /** Model provider interface (PRD §17). Implementations live in @appmind/model. */
2
+ export {};
3
+ //# sourceMappingURL=model.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model.js","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"AAAA,kFAAkF"}
@@ -0,0 +1,58 @@
1
+ import type { RetrievalResult } from "@appmind/knowledge";
2
+ import type { AppMindAction } from "./actions.js";
3
+ import type { ChatMessage, ToolSpec } from "./model.js";
4
+ /**
5
+ * Built-in token estimate, shaped like BPE tokenizers (cl100k/Llama-style):
6
+ * a common word is ~1 token and long words split every ~6 chars, digits group
7
+ * in threes, each punctuation/symbol is its own token, and CJK is ~1 token per
8
+ * character. Within ~15% of real tokenizers on prose and code — far closer
9
+ * than chars/4, which undercounts code and CJK badly.
10
+ *
11
+ * Still an estimate: tokenizers are model-specific and large (>1 MB), so core
12
+ * doesn't bundle one. For exact budgets pass `prompt.countTokens`.
13
+ */
14
+ export declare function estimateTokens(text: string): number;
15
+ /** A token counter: the built-in estimate, or a real tokenizer you supply. */
16
+ export type TokenCounter = (text: string) => number;
17
+ export interface PromptBudget {
18
+ /** Total token budget the prompt should target (default: small-model ~4K ctx). */
19
+ maxTokens: number;
20
+ /** Tokens reserved for the model's output. */
21
+ reservedOutputTokens: number;
22
+ /** Hard cap on characters kept from any single knowledge chunk. */
23
+ perChunkCharCap: number;
24
+ /** Max prior turns of conversation to keep. */
25
+ maxHistoryTurns: number;
26
+ /**
27
+ * Token counter used for all budgeting (default: `estimateTokens`). Plug in
28
+ * your model's real tokenizer for exact budgets, e.g. js-tiktoken.
29
+ */
30
+ countTokens?: TokenCounter;
31
+ }
32
+ export declare const DEFAULT_PROMPT_BUDGET: PromptBudget;
33
+ /**
34
+ * Assemble the structured system prompt (PRD §40) within a token budget.
35
+ *
36
+ * Fill priority: system instructions → application context → top-ranked
37
+ * knowledge (drop lowest-ranked / truncate per chunk until it fits) → available
38
+ * actions. History and the user message are budgeted separately in the messages
39
+ * array; the caller passes the tokens those consume as `usedTokens`.
40
+ */
41
+ export declare function buildSystemPrompt(contextBlock: string, knowledge: RetrievalResult[], actions: AppMindAction[], options?: {
42
+ budget?: Partial<PromptBudget>;
43
+ usedTokens?: number;
44
+ }): string;
45
+ export declare function toToolSpecs(actions: AppMindAction[]): ToolSpec[];
46
+ /**
47
+ * Best-effort extraction of a tool call from a plain-text model response, for
48
+ * providers that don't emit structured tool_call events. Looks for a JSON
49
+ * object containing a "tool" key.
50
+ */
51
+ export declare function parseToolCallFromText(text: string): {
52
+ name: string;
53
+ arguments: unknown;
54
+ } | undefined;
55
+ /** Keep only the last `maxTurns` messages of history (a turn = one message). */
56
+ export declare function windowHistory(history: ChatMessage[], maxTurns: number): ChatMessage[];
57
+ export declare function toChatMessages(history: ChatMessage[], userMessage: string, maxTurns?: number): ChatMessage[];
58
+ //# sourceMappingURL=runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAExD;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAUnD;AAMD,8EAA8E;AAC9E,MAAM,MAAM,YAAY,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;AAEpD,MAAM,WAAW,YAAY;IAC3B,kFAAkF;IAClF,SAAS,EAAE,MAAM,CAAC;IAClB,8CAA8C;IAC9C,oBAAoB,EAAE,MAAM,CAAC;IAC7B,mEAAmE;IACnE,eAAe,EAAE,MAAM,CAAC;IACxB,+CAA+C;IAC/C,eAAe,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,WAAW,CAAC,EAAE,YAAY,CAAC;CAC5B;AAED,eAAO,MAAM,qBAAqB,EAAE,YAKnC,CAAC;AAkBF;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,eAAe,EAAE,EAC5B,OAAO,EAAE,aAAa,EAAE,EACxB,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAO,GACpE,MAAM,CAgDR;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,aAAa,EAAE,GAAG,QAAQ,EAAE,CAMhE;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,MAAM,GACX;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,GAAG,SAAS,CAYlD;AAED,gFAAgF;AAChF,wBAAgB,aAAa,CAAC,OAAO,EAAE,WAAW,EAAE,EAAE,QAAQ,EAAE,MAAM,GAAG,WAAW,EAAE,CAGrF;AAED,wBAAgB,cAAc,CAC5B,OAAO,EAAE,WAAW,EAAE,EACtB,WAAW,EAAE,MAAM,EACnB,QAAQ,SAAwC,GAC/C,WAAW,EAAE,CAEf"}
@@ -0,0 +1,135 @@
1
+ /**
2
+ * Built-in token estimate, shaped like BPE tokenizers (cl100k/Llama-style):
3
+ * a common word is ~1 token and long words split every ~6 chars, digits group
4
+ * in threes, each punctuation/symbol is its own token, and CJK is ~1 token per
5
+ * character. Within ~15% of real tokenizers on prose and code — far closer
6
+ * than chars/4, which undercounts code and CJK badly.
7
+ *
8
+ * Still an estimate: tokenizers are model-specific and large (>1 MB), so core
9
+ * doesn't bundle one. For exact budgets pass `prompt.countTokens`.
10
+ */
11
+ export function estimateTokens(text) {
12
+ let tokens = 0;
13
+ for (const m of text.matchAll(TOKEN_PIECES)) {
14
+ const piece = m[0];
15
+ if (CJK.test(piece))
16
+ tokens += 1;
17
+ else if (/^[0-9]+$/.test(piece))
18
+ tokens += Math.ceil(piece.length / 3);
19
+ else if (WORD.test(piece))
20
+ tokens += 1 + Math.floor((piece.length - 1) / 6);
21
+ else
22
+ tokens += 1; // punctuation / symbol
23
+ }
24
+ return Math.max(tokens, Math.ceil(text.length / 6));
25
+ }
26
+ const WORD = /^[A-Za-z_\u00c0-\u024f]+$/;
27
+ const CJK = /[\u3040-\u30ff\u3400-\u9fff\uac00-\ud7af]/;
28
+ const TOKEN_PIECES = /[\u3040-\u30ff\u3400-\u9fff\uac00-\ud7af]|[0-9]+|[A-Za-z_\u00c0-\u024f]+|[^\s]/g;
29
+ export const DEFAULT_PROMPT_BUDGET = {
30
+ maxTokens: 4096,
31
+ reservedOutputTokens: 1024,
32
+ perChunkCharCap: 1200,
33
+ maxHistoryTurns: 6,
34
+ };
35
+ const BASE_INSTRUCTIONS = [
36
+ "SYSTEM INSTRUCTIONS",
37
+ "You are AppMind, an assistant embedded inside a web application.",
38
+ "Answer the user's question directly and concisely using the APPLICATION CONTEXT",
39
+ "and RELEVANT PRODUCT KNOWLEDGE below. If the knowledge does not cover the",
40
+ "question, say so briefly. Do not invent facts, and do not output JSON.",
41
+ ].join("\n");
42
+ const TOOL_INSTRUCTIONS = [
43
+ "You can also perform actions, but ONLY when the user explicitly asks you to do",
44
+ "one of the AVAILABLE ACTIONS listed below. To perform one, reply with ONLY a",
45
+ 'JSON object {"tool":"<name>","arguments":{...}} where <name> is exactly one of',
46
+ "the AVAILABLE ACTIONS — never invent an action name. For any informational or",
47
+ "factual question, answer in plain language and do NOT output JSON.",
48
+ ].join("\n");
49
+ /**
50
+ * Assemble the structured system prompt (PRD §40) within a token budget.
51
+ *
52
+ * Fill priority: system instructions → application context → top-ranked
53
+ * knowledge (drop lowest-ranked / truncate per chunk until it fits) → available
54
+ * actions. History and the user message are budgeted separately in the messages
55
+ * array; the caller passes the tokens those consume as `usedTokens`.
56
+ */
57
+ export function buildSystemPrompt(contextBlock, knowledge, actions, options = {}) {
58
+ const budget = { ...DEFAULT_PROMPT_BUDGET, ...options.budget };
59
+ const usedTokens = options.usedTokens ?? 0;
60
+ const count = budget.countTokens ?? estimateTokens;
61
+ // Only mention tools/JSON when actions are actually available, so the model
62
+ // doesn't hallucinate a tool call for a plain informational question.
63
+ const instructions = actions.length > 0 ? `${BASE_INSTRUCTIONS}\n\n${TOOL_INSTRUCTIONS}` : BASE_INSTRUCTIONS;
64
+ const parts = [instructions];
65
+ let spent = count(instructions) + usedTokens;
66
+ const ceiling = budget.maxTokens - budget.reservedOutputTokens;
67
+ // Application context is high priority — always included (it's small).
68
+ if (contextBlock.trim()) {
69
+ parts.push(contextBlock);
70
+ spent += count(contextBlock);
71
+ }
72
+ // Available actions are essential for tool calling — reserve them before knowledge.
73
+ const actionsBlock = actions.length > 0
74
+ ? `AVAILABLE ACTIONS\n${actions.map((a) => `- ${a.name}: ${a.description}`).join("\n")}`
75
+ : "";
76
+ const actionsTokens = actionsBlock ? count(actionsBlock) : 0;
77
+ // Fill knowledge with whatever budget remains after reserving actions.
78
+ const knowledgeCeiling = ceiling - actionsTokens;
79
+ const included = [];
80
+ for (let i = 0; i < knowledge.length; i++) {
81
+ const r = knowledge[i];
82
+ const content = r.content.length > budget.perChunkCharCap
83
+ ? r.content.slice(0, budget.perChunkCharCap) + "…"
84
+ : r.content;
85
+ const block = `[${i + 1}] ${r.title}${r.section ? ` — ${r.section}` : ""}\n${content}`;
86
+ const blockTokens = count(block);
87
+ if (spent + blockTokens > knowledgeCeiling)
88
+ break; // drop remaining lower-ranked chunks
89
+ included.push(block);
90
+ spent += blockTokens;
91
+ }
92
+ if (included.length > 0) {
93
+ parts.push(`RELEVANT PRODUCT KNOWLEDGE\n${included.join("\n\n")}`);
94
+ }
95
+ if (actionsBlock)
96
+ parts.push(actionsBlock);
97
+ return parts.join("\n\n");
98
+ }
99
+ export function toToolSpecs(actions) {
100
+ return actions.map((a) => ({
101
+ name: a.name,
102
+ description: a.description,
103
+ parameters: a.parameters,
104
+ }));
105
+ }
106
+ /**
107
+ * Best-effort extraction of a tool call from a plain-text model response, for
108
+ * providers that don't emit structured tool_call events. Looks for a JSON
109
+ * object containing a "tool" key.
110
+ */
111
+ export function parseToolCallFromText(text) {
112
+ const match = text.match(/\{[\s\S]*"tool"[\s\S]*\}/);
113
+ if (!match)
114
+ return undefined;
115
+ try {
116
+ const parsed = JSON.parse(match[0]);
117
+ if (typeof parsed.tool === "string") {
118
+ return { name: parsed.tool, arguments: parsed.arguments ?? {} };
119
+ }
120
+ }
121
+ catch {
122
+ /* not a tool call */
123
+ }
124
+ return undefined;
125
+ }
126
+ /** Keep only the last `maxTurns` messages of history (a turn = one message). */
127
+ export function windowHistory(history, maxTurns) {
128
+ if (history.length <= maxTurns)
129
+ return history;
130
+ return history.slice(history.length - maxTurns);
131
+ }
132
+ export function toChatMessages(history, userMessage, maxTurns = DEFAULT_PROMPT_BUDGET.maxHistoryTurns) {
133
+ return [...windowHistory(history, maxTurns), { role: "user", content: userMessage }];
134
+ }
135
+ //# sourceMappingURL=runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import type { KnowledgeIndex } from "@appmind/knowledge";
2
+ /**
3
+ * Persistence interface for the local knowledge index (PRD §24).
4
+ * MVP adapter is IndexedDB (@appmind/storage-indexeddb); an in-memory
5
+ * fallback ships here for SSR/Node.
6
+ */
7
+ export interface AppMindStorage {
8
+ getIndex(version: string): Promise<KnowledgeIndex | undefined>;
9
+ /**
10
+ * Store `index` as the latest version and drop any older ones — only the
11
+ * current index is ever read, so keeping old versions just wastes the
12
+ * user's disk quota.
13
+ */
14
+ putIndex(index: KnowledgeIndex): Promise<void>;
15
+ getStoredVersion(): Promise<string | undefined>;
16
+ clear(): Promise<void>;
17
+ }
18
+ /** Volatile fallback — never persists. Used on the server / when no adapter is set. */
19
+ export declare class MemoryStorage implements AppMindStorage {
20
+ private indexes;
21
+ private latest;
22
+ getIndex(version: string): Promise<KnowledgeIndex | undefined>;
23
+ putIndex(index: KnowledgeIndex): Promise<void>;
24
+ getStoredVersion(): Promise<string | undefined>;
25
+ clear(): Promise<void>;
26
+ }
27
+ //# sourceMappingURL=storage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEzD;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC,CAAC;IAC/D;;;;OAIG;IACH,QAAQ,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/C,gBAAgB,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAChD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED,uFAAuF;AACvF,qBAAa,aAAc,YAAW,cAAc;IAClD,OAAO,CAAC,OAAO,CAAqC;IACpD,OAAO,CAAC,MAAM,CAAqB;IAE7B,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC;IAG9D,QAAQ,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAK9C,gBAAgB,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAG/C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAI7B"}
@@ -0,0 +1,22 @@
1
+ /** Volatile fallback — never persists. Used on the server / when no adapter is set. */
2
+ export class MemoryStorage {
3
+ constructor() {
4
+ this.indexes = new Map();
5
+ }
6
+ async getIndex(version) {
7
+ return this.indexes.get(version);
8
+ }
9
+ async putIndex(index) {
10
+ this.indexes.clear();
11
+ this.indexes.set(index.manifest.version, index);
12
+ this.latest = index.manifest.version;
13
+ }
14
+ async getStoredVersion() {
15
+ return this.latest;
16
+ }
17
+ async clear() {
18
+ this.indexes.clear();
19
+ this.latest = undefined;
20
+ }
21
+ }
22
+ //# sourceMappingURL=storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.js","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"AAmBA,uFAAuF;AACvF,MAAM,OAAO,aAAa;IAA1B;QACU,YAAO,GAAG,IAAI,GAAG,EAA0B,CAAC;IAkBtD,CAAC;IAfC,KAAK,CAAC,QAAQ,CAAC,OAAe;QAC5B,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACnC,CAAC;IACD,KAAK,CAAC,QAAQ,CAAC,KAAqB;QAClC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QACrB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QAChD,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC;IACvC,CAAC;IACD,KAAK,CAAC,gBAAgB;QACpB,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IACD,KAAK,CAAC,KAAK;QACT,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QACrB,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC;IAC1B,CAAC;CACF"}
package/package.json CHANGED
@@ -1,6 +1,31 @@
1
1
  {
2
2
  "name": "@appmind/core",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "0.2.0",
4
+ "description": "AppMind core runtime: agent orchestration, UI context, action registry, and provider interfaces.",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "main": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist"
17
+ ],
18
+ "dependencies": {
19
+ "@appmind/knowledge": "0.2.0"
20
+ },
21
+ "publishConfig": {
22
+ "access": "public"
23
+ },
24
+ "homepage": "https://github.com/dmitripoli/appmind#readme",
25
+ "bugs": {
26
+ "url": "https://github.com/dmitripoli/appmind/issues"
27
+ },
28
+ "scripts": {
29
+ "build": "tsc -b"
30
+ }
6
31
  }