@lapis-notes/ai 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/CHANGELOG.md +6 -0
- package/LICENSE.md +8 -0
- package/README.md +20 -0
- package/dist/ai-plugin.d.ts +88 -0
- package/dist/ai-plugin.js +742 -0
- package/dist/bootstrap/build.d.ts +15 -0
- package/dist/bootstrap/build.js +28 -0
- package/dist/bootstrap/folder-instructions.d.ts +4 -0
- package/dist/bootstrap/folder-instructions.js +49 -0
- package/dist/bootstrap/format.d.ts +2 -0
- package/dist/bootstrap/format.js +46 -0
- package/dist/bootstrap/instructions.d.ts +1 -0
- package/dist/bootstrap/instructions.js +8 -0
- package/dist/bootstrap/types.d.ts +36 -0
- package/dist/bootstrap/types.js +3 -0
- package/dist/catalog/ai-catalog-panel.svelte +742 -0
- package/dist/catalog/ai-catalog-panel.svelte.d.ts +13 -0
- package/dist/catalog/ai-catalog-view-type.d.ts +1 -0
- package/dist/catalog/ai-catalog-view-type.js +1 -0
- package/dist/catalog/ai-catalog-view.d.ts +22 -0
- package/dist/catalog/ai-catalog-view.js +48 -0
- package/dist/catalog/filter.d.ts +3 -0
- package/dist/catalog/filter.js +24 -0
- package/dist/catalog/inventory.d.ts +21 -0
- package/dist/catalog/inventory.js +255 -0
- package/dist/catalog/tree.d.ts +12 -0
- package/dist/catalog/tree.js +60 -0
- package/dist/catalog/types.d.ts +44 -0
- package/dist/catalog/types.js +1 -0
- package/dist/chat/ai-approval-card.svelte +54 -0
- package/dist/chat/ai-approval-card.svelte.d.ts +9 -0
- package/dist/chat/ai-chat-panel.svelte +1288 -0
- package/dist/chat/ai-chat-panel.svelte.d.ts +50 -0
- package/dist/chat/ai-inventory-result.css +55 -0
- package/dist/chat/ai-inventory-result.svelte +63 -0
- package/dist/chat/ai-inventory-result.svelte.d.ts +5 -0
- package/dist/chat/ai-question-card.svelte +132 -0
- package/dist/chat/ai-question-card.svelte.d.ts +9 -0
- package/dist/chat/ai-view-bootstrap.d.ts +13 -0
- package/dist/chat/ai-view-bootstrap.js +86 -0
- package/dist/chat/ai-view-panel.svelte +89 -0
- package/dist/chat/ai-view-panel.svelte.d.ts +13 -0
- package/dist/chat/ai-view-type.d.ts +1 -0
- package/dist/chat/ai-view-type.js +1 -0
- package/dist/chat/ai-view.d.ts +60 -0
- package/dist/chat/ai-view.js +121 -0
- package/dist/chat/chat-controller.svelte.d.ts +82 -0
- package/dist/chat/chat-controller.svelte.js +1926 -0
- package/dist/chat/chat-items.d.ts +88 -0
- package/dist/chat/chat-items.js +9 -0
- package/dist/chat/chat-mentions.d.ts +15 -0
- package/dist/chat/chat-mentions.js +77 -0
- package/dist/chat/chat-result-views.d.ts +5 -0
- package/dist/chat/chat-result-views.js +15 -0
- package/dist/chat/chat-session.d.ts +28 -0
- package/dist/chat/chat-session.js +50 -0
- package/dist/chat/chat-status.d.ts +1 -0
- package/dist/chat/chat-status.js +3 -0
- package/dist/chat/chat-time.d.ts +18 -0
- package/dist/chat/chat-time.js +90 -0
- package/dist/chat/chat-tool-display.d.ts +17 -0
- package/dist/chat/chat-tool-display.js +213 -0
- package/dist/chat/chat-tool-identity.d.ts +4 -0
- package/dist/chat/chat-tool-identity.js +42 -0
- package/dist/chat/chat-trace.d.ts +6 -0
- package/dist/chat/chat-trace.js +256 -0
- package/dist/chat/live-runtime-unavailable.d.ts +1 -0
- package/dist/chat/live-runtime-unavailable.js +1 -0
- package/dist/commands/agent.d.ts +8 -0
- package/dist/commands/agent.js +38 -0
- package/dist/commands/catalog.d.ts +18 -0
- package/dist/commands/catalog.js +115 -0
- package/dist/commands/discovery.d.ts +36 -0
- package/dist/commands/discovery.js +151 -0
- package/dist/commands/groups.d.ts +16 -0
- package/dist/commands/groups.js +121 -0
- package/dist/commands/inspect.d.ts +18 -0
- package/dist/commands/inspect.js +29 -0
- package/dist/commands/markdown.d.ts +21 -0
- package/dist/commands/markdown.js +117 -0
- package/dist/commands/parser.d.ts +4 -0
- package/dist/commands/parser.js +24 -0
- package/dist/commands/reserved.d.ts +4 -0
- package/dist/commands/reserved.js +107 -0
- package/dist/commands/router.d.ts +17 -0
- package/dist/commands/router.js +170 -0
- package/dist/commands/seed.d.ts +4 -0
- package/dist/commands/seed.js +8 -0
- package/dist/commands/types.d.ts +54 -0
- package/dist/commands/types.js +1 -0
- package/dist/commands/user-agents-node.d.ts +3 -0
- package/dist/commands/user-agents-node.js +52 -0
- package/dist/commands/user-agents.d.ts +22 -0
- package/dist/commands/user-agents.js +40 -0
- package/dist/conversations/approval-grants.d.ts +20 -0
- package/dist/conversations/approval-grants.js +75 -0
- package/dist/conversations/binding-state.d.ts +6 -0
- package/dist/conversations/binding-state.js +35 -0
- package/dist/conversations/context-handoff.d.ts +25 -0
- package/dist/conversations/context-handoff.js +207 -0
- package/dist/conversations/conversation-index-coordinator.d.ts +18 -0
- package/dist/conversations/conversation-index-coordinator.js +81 -0
- package/dist/conversations/conversation-index.d.ts +16 -0
- package/dist/conversations/conversation-index.js +125 -0
- package/dist/conversations/conversation-locator.d.ts +2 -0
- package/dist/conversations/conversation-locator.js +20 -0
- package/dist/conversations/conversation-palette.d.ts +18 -0
- package/dist/conversations/conversation-palette.js +29 -0
- package/dist/conversations/conversation-repository.d.ts +39 -0
- package/dist/conversations/conversation-repository.js +213 -0
- package/dist/conversations/handoff-summary.d.ts +48 -0
- package/dist/conversations/handoff-summary.js +269 -0
- package/dist/conversations/hashes.d.ts +5 -0
- package/dist/conversations/hashes.js +40 -0
- package/dist/conversations/history-creation-scope.d.ts +12 -0
- package/dist/conversations/history-creation-scope.js +44 -0
- package/dist/conversations/jsonl.d.ts +10 -0
- package/dist/conversations/jsonl.js +41 -0
- package/dist/conversations/memory-transcript-store.d.ts +15 -0
- package/dist/conversations/memory-transcript-store.js +119 -0
- package/dist/conversations/paths.d.ts +14 -0
- package/dist/conversations/paths.js +92 -0
- package/dist/conversations/redaction.d.ts +13 -0
- package/dist/conversations/redaction.js +94 -0
- package/dist/conversations/reveal-scope.d.ts +3 -0
- package/dist/conversations/reveal-scope.js +8 -0
- package/dist/conversations/scope-resolver.d.ts +11 -0
- package/dist/conversations/scope-resolver.js +18 -0
- package/dist/conversations/scope-tree.d.ts +10 -0
- package/dist/conversations/scope-tree.js +71 -0
- package/dist/conversations/transcript-projection.d.ts +9 -0
- package/dist/conversations/transcript-projection.js +409 -0
- package/dist/conversations/transcript-store.d.ts +24 -0
- package/dist/conversations/transcript-store.js +27 -0
- package/dist/conversations/types.d.ts +224 -0
- package/dist/conversations/types.js +12 -0
- package/dist/conversations/validation.d.ts +4 -0
- package/dist/conversations/validation.js +383 -0
- package/dist/conversations/vault-transcript-store.d.ts +22 -0
- package/dist/conversations/vault-transcript-store.js +219 -0
- package/dist/core/event-queue.d.ts +6 -0
- package/dist/core/event-queue.js +39 -0
- package/dist/core/types.d.ts +241 -0
- package/dist/core/types.js +50 -0
- package/dist/history/ai-history-panel.svelte +937 -0
- package/dist/history/ai-history-panel.svelte.d.ts +17 -0
- package/dist/history/ai-history-view-type.d.ts +1 -0
- package/dist/history/ai-history-view-type.js +1 -0
- package/dist/history/ai-history-view.d.ts +26 -0
- package/dist/history/ai-history-view.js +51 -0
- package/dist/history/conversation-history-tree.d.ts +15 -0
- package/dist/history/conversation-history-tree.js +71 -0
- package/dist/host/agent-workspace.d.ts +6 -0
- package/dist/host/agent-workspace.js +16 -0
- package/dist/host/create-host-runtimes.d.ts +2 -0
- package/dist/host/create-host-runtimes.js +14 -0
- package/dist/host/desktop-process-host.d.ts +6 -0
- package/dist/host/desktop-process-host.js +74 -0
- package/dist/host/host-runtime-availability.d.ts +1 -0
- package/dist/host/host-runtime-availability.js +3 -0
- package/dist/host/process-host.d.ts +31 -0
- package/dist/host/process-host.js +6 -0
- package/dist/index.d.ts +69 -0
- package/dist/index.js +49 -0
- package/dist/jsonl/ai-jsonl-preview.d.ts +27 -0
- package/dist/jsonl/ai-jsonl-preview.js +68 -0
- package/dist/jsonl/ai-jsonl-view-type.d.ts +1 -0
- package/dist/jsonl/ai-jsonl-view-type.js +1 -0
- package/dist/jsonl/ai-jsonl-view.d.ts +16 -0
- package/dist/jsonl/ai-jsonl-view.js +57 -0
- package/dist/jsonl/ai-jsonl-view.svelte +260 -0
- package/dist/jsonl/ai-jsonl-view.svelte.d.ts +9 -0
- package/dist/memory/candidate-extractor.d.ts +25 -0
- package/dist/memory/candidate-extractor.js +191 -0
- package/dist/memory/forget-confirmation.d.ts +3 -0
- package/dist/memory/forget-confirmation.js +45 -0
- package/dist/memory/hashes.d.ts +5 -0
- package/dist/memory/hashes.js +37 -0
- package/dist/memory/memory-ingestion-coordinator.d.ts +19 -0
- package/dist/memory/memory-ingestion-coordinator.js +108 -0
- package/dist/memory/memory-record-store.d.ts +62 -0
- package/dist/memory/memory-record-store.js +369 -0
- package/dist/memory/memory-scheduler.d.ts +21 -0
- package/dist/memory/memory-scheduler.js +143 -0
- package/dist/memory/memory-tools.d.ts +61 -0
- package/dist/memory/memory-tools.js +99 -0
- package/dist/memory/native-memory-service.d.ts +72 -0
- package/dist/memory/native-memory-service.js +1256 -0
- package/dist/memory/paths.d.ts +13 -0
- package/dist/memory/paths.js +60 -0
- package/dist/memory/runtime-consolidation-provider.d.ts +18 -0
- package/dist/memory/runtime-consolidation-provider.js +154 -0
- package/dist/memory/types.d.ts +139 -0
- package/dist/memory/types.js +1 -0
- package/dist/providers/acp-model-provider.d.ts +11 -0
- package/dist/providers/acp-model-provider.js +99 -0
- package/dist/providers/codex-model-catalog.d.ts +7 -0
- package/dist/providers/codex-model-catalog.js +179 -0
- package/dist/providers/codex-model-provider.d.ts +12 -0
- package/dist/providers/codex-model-provider.js +42 -0
- package/dist/providers/model-provider.d.ts +26 -0
- package/dist/providers/model-provider.js +26 -0
- package/dist/public-components.d.ts +3 -0
- package/dist/public-components.js +3 -0
- package/dist/registry/runtime-registry.d.ts +11 -0
- package/dist/registry/runtime-registry.js +71 -0
- package/dist/registry/select-runtime.d.ts +9 -0
- package/dist/registry/select-runtime.js +31 -0
- package/dist/runtime-adapters.d.ts +16 -0
- package/dist/runtime-adapters.js +9 -0
- package/dist/runtimes/acp/acp-event-mapper.d.ts +56 -0
- package/dist/runtimes/acp/acp-event-mapper.js +237 -0
- package/dist/runtimes/acp/acp-runtime.d.ts +46 -0
- package/dist/runtimes/acp/acp-runtime.js +165 -0
- package/dist/runtimes/acp/desktop-acp-backend.d.ts +16 -0
- package/dist/runtimes/acp/desktop-acp-backend.js +243 -0
- package/dist/runtimes/codex/app-server-protocol.d.ts +28 -0
- package/dist/runtimes/codex/app-server-protocol.js +274 -0
- package/dist/runtimes/codex/codex-runtime.d.ts +24 -0
- package/dist/runtimes/codex/codex-runtime.js +318 -0
- package/dist/runtimes/fake/fake-runtime.d.ts +51 -0
- package/dist/runtimes/fake/fake-runtime.js +257 -0
- package/dist/sessions/plugin-data.d.ts +8 -0
- package/dist/sessions/plugin-data.js +29 -0
- package/dist/sessions/session-store.d.ts +47 -0
- package/dist/sessions/session-store.js +117 -0
- package/dist/settings/acp-agents.d.ts +8 -0
- package/dist/settings/acp-agents.js +11 -0
- package/dist/settings/ai-settings-tab.d.ts +8 -0
- package/dist/settings/ai-settings-tab.js +249 -0
- package/dist/settings/ai-settings.d.ts +43 -0
- package/dist/settings/ai-settings.js +147 -0
- package/dist/settings/app-tool-setting-rows.d.ts +16 -0
- package/dist/settings/app-tool-setting-rows.js +30 -0
- package/dist/settings/register-ai-settings.d.ts +3 -0
- package/dist/settings/register-ai-settings.js +393 -0
- package/dist/skills/activation.d.ts +2 -0
- package/dist/skills/activation.js +20 -0
- package/dist/skills/bundled/lapis-notes.d.ts +3 -0
- package/dist/skills/bundled/lapis-notes.js +52 -0
- package/dist/skills/bundled/research.d.ts +6 -0
- package/dist/skills/bundled/research.js +29 -0
- package/dist/skills/discovery.d.ts +21 -0
- package/dist/skills/discovery.js +227 -0
- package/dist/skills/manifest.d.ts +3 -0
- package/dist/skills/manifest.js +39 -0
- package/dist/skills/parser.d.ts +12 -0
- package/dist/skills/parser.js +124 -0
- package/dist/skills/registry.d.ts +21 -0
- package/dist/skills/registry.js +89 -0
- package/dist/skills/seed.d.ts +5 -0
- package/dist/skills/seed.js +18 -0
- package/dist/skills/skill-tools.d.ts +8 -0
- package/dist/skills/skill-tools.js +113 -0
- package/dist/skills/types.d.ts +67 -0
- package/dist/skills/types.js +1 -0
- package/dist/styles.css +514 -0
- package/dist/tools/app-tool-host.d.ts +47 -0
- package/dist/tools/app-tool-host.js +419 -0
- package/dist/tools/desktop-app-tool-bridge.d.ts +23 -0
- package/dist/tools/desktop-app-tool-bridge.js +223 -0
- package/dist/tools/mcp-server-registry.d.ts +7 -0
- package/dist/tools/mcp-server-registry.js +30 -0
- package/manifest.json +34 -0
- package/package.json +83 -0
- package/styles.css +1 -0
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import type { AgentEventSource, ApprovalRequest, UserInputRequest } from "../core/types";
|
|
2
|
+
export type AiChatApprovalStatus = "pending" | "approved" | "rejected" | "answered" | "cancelled";
|
|
3
|
+
export type AiChatItem = ({
|
|
4
|
+
id: string;
|
|
5
|
+
type: "message";
|
|
6
|
+
role: "user" | "assistant";
|
|
7
|
+
text: string;
|
|
8
|
+
createdAt?: string;
|
|
9
|
+
} | {
|
|
10
|
+
id: string;
|
|
11
|
+
type: "thinking";
|
|
12
|
+
text: string;
|
|
13
|
+
kind?: "reasoning" | "summary" | "plan";
|
|
14
|
+
state: "streaming" | "done";
|
|
15
|
+
createdAt?: string;
|
|
16
|
+
} | {
|
|
17
|
+
id: string;
|
|
18
|
+
type: "tool";
|
|
19
|
+
toolId: string;
|
|
20
|
+
name: string;
|
|
21
|
+
server?: string;
|
|
22
|
+
state: "running" | "completed" | "error";
|
|
23
|
+
input?: string;
|
|
24
|
+
output?: string;
|
|
25
|
+
createdAt?: string;
|
|
26
|
+
} | {
|
|
27
|
+
id: string;
|
|
28
|
+
type: "approval";
|
|
29
|
+
request: ApprovalRequest;
|
|
30
|
+
status: AiChatApprovalStatus;
|
|
31
|
+
responseOptionId?: string;
|
|
32
|
+
createdAt?: string;
|
|
33
|
+
} | {
|
|
34
|
+
id: string;
|
|
35
|
+
type: "question";
|
|
36
|
+
request: UserInputRequest;
|
|
37
|
+
status: "pending" | "answered" | "cancelled";
|
|
38
|
+
createdAt?: string;
|
|
39
|
+
} | {
|
|
40
|
+
id: string;
|
|
41
|
+
type: "status";
|
|
42
|
+
text: string;
|
|
43
|
+
layout?: "report" | "inventory";
|
|
44
|
+
inventory?: AiChatInventory;
|
|
45
|
+
createdAt?: string;
|
|
46
|
+
} | {
|
|
47
|
+
id: string;
|
|
48
|
+
type: "error";
|
|
49
|
+
text: string;
|
|
50
|
+
createdAt?: string;
|
|
51
|
+
} | {
|
|
52
|
+
id: string;
|
|
53
|
+
type: "command";
|
|
54
|
+
command: string;
|
|
55
|
+
origin: "app" | "extension" | "skill" | "native-agent";
|
|
56
|
+
arguments?: string;
|
|
57
|
+
status: "completed" | "failed" | "cancelled";
|
|
58
|
+
text: string;
|
|
59
|
+
createdAt?: string;
|
|
60
|
+
} | {
|
|
61
|
+
id: string;
|
|
62
|
+
type: "skill-activation";
|
|
63
|
+
skillId: string;
|
|
64
|
+
skillName: string;
|
|
65
|
+
version: string;
|
|
66
|
+
origin: "user" | "model" | "app";
|
|
67
|
+
arguments?: string;
|
|
68
|
+
text: string;
|
|
69
|
+
createdAt?: string;
|
|
70
|
+
}) & {
|
|
71
|
+
agentBindingId?: string;
|
|
72
|
+
source?: AgentEventSource;
|
|
73
|
+
};
|
|
74
|
+
export type AiChatInventoryKind = "skills" | "tools";
|
|
75
|
+
export type AiChatInventoryItem = {
|
|
76
|
+
name: string;
|
|
77
|
+
description?: string;
|
|
78
|
+
path?: string;
|
|
79
|
+
kind: "skill" | "tool";
|
|
80
|
+
};
|
|
81
|
+
export type AiChatInventory = {
|
|
82
|
+
kind: AiChatInventoryKind;
|
|
83
|
+
items: AiChatInventoryItem[];
|
|
84
|
+
};
|
|
85
|
+
export declare function createChatItemId(prefix: string, index: number): string;
|
|
86
|
+
export declare function isSlashCommandNotice(item: AiChatItem): item is Extract<AiChatItem, {
|
|
87
|
+
type: "status";
|
|
88
|
+
}>;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export function createChatItemId(prefix, index) {
|
|
2
|
+
return `${prefix}-${index}`;
|
|
3
|
+
}
|
|
4
|
+
export function isSlashCommandNotice(item) {
|
|
5
|
+
return (item.type === "status" &&
|
|
6
|
+
(item.layout === "report" ||
|
|
7
|
+
item.layout === "inventory" ||
|
|
8
|
+
item.text.includes("\n")));
|
|
9
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export type VaultFileRef = {
|
|
2
|
+
path: string;
|
|
3
|
+
name: string;
|
|
4
|
+
};
|
|
5
|
+
export declare function normalizeMentionPath(path: string): string;
|
|
6
|
+
export declare function formatFileMention(path: string): string;
|
|
7
|
+
export declare function extractMentionQuery(input: string): string | null;
|
|
8
|
+
export declare function extractMentionPaths(input: string): string[];
|
|
9
|
+
export declare function mergeAttachmentPaths(...lists: Array<Iterable<string> | undefined>): string[];
|
|
10
|
+
export declare function mentionTokensFromText(text: string): Array<{
|
|
11
|
+
value: string;
|
|
12
|
+
label: string;
|
|
13
|
+
variant: "secondary";
|
|
14
|
+
}>;
|
|
15
|
+
export declare function searchVaultFiles(files: Iterable<VaultFileRef>, query: string, limit?: number): VaultFileRef[];
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { isLapisInternalPath } from "@lapis-notes/api/path";
|
|
2
|
+
const TRAILING_MENTION_PATTERN = /(^|\s)@(?:"([^"]*)"|([^\s"]*))$/;
|
|
3
|
+
const MENTION_PATTERN = /(^|\s)@(?:"([^"]+)"|([^\s]+))/g;
|
|
4
|
+
export function normalizeMentionPath(path) {
|
|
5
|
+
const normalized = path.trim().replaceAll("\\", "/");
|
|
6
|
+
return normalized.startsWith("./") ? normalized.slice(2) : normalized;
|
|
7
|
+
}
|
|
8
|
+
export function formatFileMention(path) {
|
|
9
|
+
const normalized = normalizeMentionPath(path);
|
|
10
|
+
return /\s/.test(normalized)
|
|
11
|
+
? `@"${normalized.replaceAll('"', '\\"')}"`
|
|
12
|
+
: `@${normalized}`;
|
|
13
|
+
}
|
|
14
|
+
export function extractMentionQuery(input) {
|
|
15
|
+
const match = TRAILING_MENTION_PATTERN.exec(input);
|
|
16
|
+
if (!match)
|
|
17
|
+
return null;
|
|
18
|
+
return (match[2] ?? match[3] ?? "").trim();
|
|
19
|
+
}
|
|
20
|
+
export function extractMentionPaths(input) {
|
|
21
|
+
const paths = [];
|
|
22
|
+
const seen = new Set();
|
|
23
|
+
for (const match of input.matchAll(MENTION_PATTERN)) {
|
|
24
|
+
const path = normalizeMentionPath((match[2] ?? match[3] ?? "").trim());
|
|
25
|
+
if (!path || seen.has(path))
|
|
26
|
+
continue;
|
|
27
|
+
seen.add(path);
|
|
28
|
+
paths.push(path);
|
|
29
|
+
}
|
|
30
|
+
return paths;
|
|
31
|
+
}
|
|
32
|
+
export function mergeAttachmentPaths(...lists) {
|
|
33
|
+
const seen = new Set();
|
|
34
|
+
const paths = [];
|
|
35
|
+
for (const list of lists) {
|
|
36
|
+
if (!list)
|
|
37
|
+
continue;
|
|
38
|
+
for (const raw of list) {
|
|
39
|
+
const path = normalizeMentionPath(raw);
|
|
40
|
+
if (!path || seen.has(path))
|
|
41
|
+
continue;
|
|
42
|
+
seen.add(path);
|
|
43
|
+
paths.push(path);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return paths;
|
|
47
|
+
}
|
|
48
|
+
export function mentionTokensFromText(text) {
|
|
49
|
+
return extractMentionPaths(text).map((path) => ({
|
|
50
|
+
value: formatFileMention(path),
|
|
51
|
+
label: path,
|
|
52
|
+
variant: "secondary",
|
|
53
|
+
}));
|
|
54
|
+
}
|
|
55
|
+
export function searchVaultFiles(files, query, limit = 20) {
|
|
56
|
+
const needle = query.trim().toLowerCase();
|
|
57
|
+
const matches = [];
|
|
58
|
+
for (const file of files) {
|
|
59
|
+
const path = normalizeMentionPath(file.path);
|
|
60
|
+
if (!path ||
|
|
61
|
+
path.startsWith("..") ||
|
|
62
|
+
path.includes("://") ||
|
|
63
|
+
isLapisInternalPath(path)) {
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
const name = file.name || path.split("/").at(-1) || path;
|
|
67
|
+
if (needle &&
|
|
68
|
+
!path.toLowerCase().includes(needle) &&
|
|
69
|
+
!name.toLowerCase().includes(needle)) {
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
matches.push({ path, name });
|
|
73
|
+
if (matches.length >= limit)
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
76
|
+
return matches;
|
|
77
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { App } from "@lapis-notes/api";
|
|
2
|
+
import type { Component } from "svelte";
|
|
3
|
+
import type { AgentResultViewProps } from "@lapis-notes/api";
|
|
4
|
+
export declare function parseToolResultPayload(value?: string): unknown;
|
|
5
|
+
export declare function resolveToolResultView(app: App | undefined, toolName: string | undefined): Component<AgentResultViewProps<App>> | undefined;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export function parseToolResultPayload(value) {
|
|
2
|
+
if (value == null || value === "")
|
|
3
|
+
return undefined;
|
|
4
|
+
try {
|
|
5
|
+
return JSON.parse(value);
|
|
6
|
+
}
|
|
7
|
+
catch {
|
|
8
|
+
return value;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
export function resolveToolResultView(app, toolName) {
|
|
12
|
+
if (!app || !toolName?.trim())
|
|
13
|
+
return undefined;
|
|
14
|
+
return app.agentResultViews?.getByTool(toolName.trim())?.component;
|
|
15
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { AgentRuntime, AgentUsage, AiThinkingLevel, ModelRef } from "../core/types";
|
|
2
|
+
import { type AgentSessionStore, type StoredAgentSession } from "../sessions/session-store";
|
|
3
|
+
import type { AiChatItem } from "./chat-items";
|
|
4
|
+
export declare function chatSessionId(workspace?: string, runtime?: string, agent?: string): string;
|
|
5
|
+
export declare function loadStoredChatSession(store: AgentSessionStore | undefined, sessionId: string): Promise<StoredAgentSession | undefined>;
|
|
6
|
+
export declare function applyStoredSessionResumePolicy(input: {
|
|
7
|
+
stored: StoredAgentSession;
|
|
8
|
+
runtime: AgentRuntime;
|
|
9
|
+
resumed: boolean;
|
|
10
|
+
}): {
|
|
11
|
+
items: AiChatItem[];
|
|
12
|
+
interrupted: boolean;
|
|
13
|
+
pendingApprovalId?: string;
|
|
14
|
+
pendingQuestionId?: string;
|
|
15
|
+
};
|
|
16
|
+
export declare function snapshotStoredChatSession(input: {
|
|
17
|
+
id: string;
|
|
18
|
+
runtime: string;
|
|
19
|
+
runtimeSessionId: string;
|
|
20
|
+
workspace?: string;
|
|
21
|
+
agent?: string;
|
|
22
|
+
model?: ModelRef;
|
|
23
|
+
thinking?: AiThinkingLevel;
|
|
24
|
+
usage?: AgentUsage;
|
|
25
|
+
items: AiChatItem[];
|
|
26
|
+
createdAt?: string;
|
|
27
|
+
interrupted?: boolean;
|
|
28
|
+
}): StoredAgentSession;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { interruptPendingInteractions, pendingApprovalIdFromItems, pendingQuestionIdFromItems, } from "../sessions/session-store";
|
|
2
|
+
export function chatSessionId(workspace, runtime, agent) {
|
|
3
|
+
const base = `ai:${workspace?.trim() || "default"}`;
|
|
4
|
+
return runtime && agent ? `${base}:${runtime}:${agent}` : base;
|
|
5
|
+
}
|
|
6
|
+
export async function loadStoredChatSession(store, sessionId) {
|
|
7
|
+
if (!store)
|
|
8
|
+
return undefined;
|
|
9
|
+
return store.get(sessionId);
|
|
10
|
+
}
|
|
11
|
+
export function applyStoredSessionResumePolicy(input) {
|
|
12
|
+
const canResume = Boolean(input.runtime.capabilities().resume && input.runtime.resume);
|
|
13
|
+
if (canResume && input.resumed) {
|
|
14
|
+
return {
|
|
15
|
+
items: [...input.stored.items],
|
|
16
|
+
interrupted: false,
|
|
17
|
+
pendingApprovalId: pendingApprovalIdFromItems(input.stored.items),
|
|
18
|
+
pendingQuestionId: pendingQuestionIdFromItems(input.stored.items),
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
const items = interruptPendingInteractions(input.stored.items);
|
|
22
|
+
return {
|
|
23
|
+
items,
|
|
24
|
+
interrupted: Boolean(input.stored.pendingApprovalId ??
|
|
25
|
+
input.stored.pendingQuestionId ??
|
|
26
|
+
pendingApprovalIdFromItems(input.stored.items) ??
|
|
27
|
+
pendingQuestionIdFromItems(input.stored.items)),
|
|
28
|
+
pendingApprovalId: undefined,
|
|
29
|
+
pendingQuestionId: undefined,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
export function snapshotStoredChatSession(input) {
|
|
33
|
+
const now = new Date().toISOString();
|
|
34
|
+
return {
|
|
35
|
+
id: input.id,
|
|
36
|
+
runtime: input.runtime,
|
|
37
|
+
runtimeSessionId: input.runtimeSessionId,
|
|
38
|
+
workspace: input.workspace,
|
|
39
|
+
agent: input.agent,
|
|
40
|
+
model: input.model,
|
|
41
|
+
thinking: input.thinking,
|
|
42
|
+
usage: input.usage ? { ...input.usage } : undefined,
|
|
43
|
+
createdAt: input.createdAt ?? now,
|
|
44
|
+
updatedAt: now,
|
|
45
|
+
interrupted: input.interrupted,
|
|
46
|
+
pendingApprovalId: pendingApprovalIdFromItems(input.items),
|
|
47
|
+
pendingQuestionId: pendingQuestionIdFromItems(input.items),
|
|
48
|
+
items: [...input.items],
|
|
49
|
+
};
|
|
50
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function shouldShowWorkingIndicator(initializing: boolean, busy: boolean, error: string | null | undefined): boolean;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { AiChatItem } from "./chat-items";
|
|
2
|
+
import type { AiChatToolItem } from "./chat-tool-display";
|
|
3
|
+
export type ChatTimelineEntry = {
|
|
4
|
+
kind: "divider";
|
|
5
|
+
id: string;
|
|
6
|
+
label: string;
|
|
7
|
+
} | {
|
|
8
|
+
kind: "item";
|
|
9
|
+
item: Exclude<AiChatItem, AiChatToolItem>;
|
|
10
|
+
} | {
|
|
11
|
+
kind: "tools";
|
|
12
|
+
id: string;
|
|
13
|
+
items: AiChatToolItem[];
|
|
14
|
+
};
|
|
15
|
+
export declare function formatChatTimestamp(iso: string): string;
|
|
16
|
+
export declare function formatChatRelativeAge(iso: string, now?: Date): string;
|
|
17
|
+
export declare function formatChatDateLabel(iso: string, now?: Date): string;
|
|
18
|
+
export declare function groupChatItemsByDate(items: AiChatItem[], now?: Date, agentLabels?: ReadonlyMap<string, string>): ChatTimelineEntry[];
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
function startOfLocalDay(date) {
|
|
2
|
+
return new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime();
|
|
3
|
+
}
|
|
4
|
+
export function formatChatTimestamp(iso) {
|
|
5
|
+
const date = new Date(iso);
|
|
6
|
+
if (Number.isNaN(date.getTime()))
|
|
7
|
+
return "";
|
|
8
|
+
return new Intl.DateTimeFormat(undefined, {
|
|
9
|
+
hour: "numeric",
|
|
10
|
+
minute: "2-digit",
|
|
11
|
+
}).format(date);
|
|
12
|
+
}
|
|
13
|
+
export function formatChatRelativeAge(iso, now = new Date()) {
|
|
14
|
+
const date = new Date(iso);
|
|
15
|
+
if (Number.isNaN(date.getTime()))
|
|
16
|
+
return "";
|
|
17
|
+
const delta = Math.max(0, now.getTime() - date.getTime());
|
|
18
|
+
const minutes = Math.floor(delta / 60_000);
|
|
19
|
+
if (minutes < 1)
|
|
20
|
+
return "now";
|
|
21
|
+
if (minutes < 60)
|
|
22
|
+
return `${minutes}m`;
|
|
23
|
+
const hours = Math.floor(minutes / 60);
|
|
24
|
+
if (hours < 24)
|
|
25
|
+
return `${hours}h`;
|
|
26
|
+
const days = Math.floor(hours / 24);
|
|
27
|
+
if (days < 7)
|
|
28
|
+
return `${days}d`;
|
|
29
|
+
return formatChatDateLabel(iso, now);
|
|
30
|
+
}
|
|
31
|
+
export function formatChatDateLabel(iso, now = new Date()) {
|
|
32
|
+
const date = new Date(iso);
|
|
33
|
+
if (Number.isNaN(date.getTime()))
|
|
34
|
+
return "";
|
|
35
|
+
const day = startOfLocalDay(date);
|
|
36
|
+
const today = startOfLocalDay(now);
|
|
37
|
+
const yesterday = today - 86_400_000;
|
|
38
|
+
if (day === today)
|
|
39
|
+
return "Today";
|
|
40
|
+
if (day === yesterday)
|
|
41
|
+
return "Yesterday";
|
|
42
|
+
return new Intl.DateTimeFormat(undefined, {
|
|
43
|
+
month: "long",
|
|
44
|
+
day: "numeric",
|
|
45
|
+
year: "numeric",
|
|
46
|
+
}).format(date);
|
|
47
|
+
}
|
|
48
|
+
export function groupChatItemsByDate(items, now = new Date(), agentLabels = new Map()) {
|
|
49
|
+
const entries = [];
|
|
50
|
+
let lastKey = null;
|
|
51
|
+
let lastBindingId;
|
|
52
|
+
for (const item of items) {
|
|
53
|
+
const parsed = item.createdAt ? new Date(item.createdAt) : null;
|
|
54
|
+
const valid = parsed && !Number.isNaN(parsed.getTime());
|
|
55
|
+
const key = valid
|
|
56
|
+
? String(startOfLocalDay(parsed))
|
|
57
|
+
: (lastKey ?? String(startOfLocalDay(now)));
|
|
58
|
+
const labelIso = valid ? item.createdAt : now.toISOString();
|
|
59
|
+
if (key !== lastKey) {
|
|
60
|
+
entries.push({
|
|
61
|
+
kind: "divider",
|
|
62
|
+
id: `date-${key}`,
|
|
63
|
+
label: formatChatDateLabel(labelIso, now),
|
|
64
|
+
});
|
|
65
|
+
lastKey = key;
|
|
66
|
+
}
|
|
67
|
+
if (item.agentBindingId &&
|
|
68
|
+
item.agentBindingId !== lastBindingId &&
|
|
69
|
+
agentLabels.has(item.agentBindingId)) {
|
|
70
|
+
entries.push({
|
|
71
|
+
kind: "divider",
|
|
72
|
+
id: `agent-${item.agentBindingId}-${item.id}`,
|
|
73
|
+
label: agentLabels.get(item.agentBindingId),
|
|
74
|
+
});
|
|
75
|
+
lastBindingId = item.agentBindingId;
|
|
76
|
+
}
|
|
77
|
+
if (item.type === "tool") {
|
|
78
|
+
const last = entries.at(-1);
|
|
79
|
+
if (last?.kind === "tools") {
|
|
80
|
+
last.items.push(item);
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
entries.push({ kind: "tools", id: `tools-${item.id}`, items: [item] });
|
|
84
|
+
}
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
entries.push({ kind: "item", item });
|
|
88
|
+
}
|
|
89
|
+
return entries;
|
|
90
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { AiChatItem } from "./chat-items";
|
|
2
|
+
export type AiChatToolItem = Extract<AiChatItem, {
|
|
3
|
+
type: "tool";
|
|
4
|
+
}>;
|
|
5
|
+
export type ToolPayloadLanguage = "json" | "bash" | "plaintext";
|
|
6
|
+
export type PresentedToolPayload = {
|
|
7
|
+
code: string;
|
|
8
|
+
language: ToolPayloadLanguage;
|
|
9
|
+
};
|
|
10
|
+
export type ToolPayloadHint = {
|
|
11
|
+
toolName?: string;
|
|
12
|
+
input?: string;
|
|
13
|
+
};
|
|
14
|
+
export declare function presentToolPayload(value?: string, hint?: ToolPayloadHint): PresentedToolPayload | undefined;
|
|
15
|
+
export declare function isOneLineAlert(payload: PresentedToolPayload): boolean;
|
|
16
|
+
export declare function toolCallTarget(input?: string, server?: string): string | undefined;
|
|
17
|
+
export declare function toolCallStatus(state: AiChatToolItem["state"]): "complete" | "error" | "running";
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
const SUMMARY_KEYS = [
|
|
2
|
+
"command",
|
|
3
|
+
"path",
|
|
4
|
+
"file",
|
|
5
|
+
"query",
|
|
6
|
+
"url",
|
|
7
|
+
"pattern",
|
|
8
|
+
"target",
|
|
9
|
+
];
|
|
10
|
+
const PRIMARY_KEYS = [
|
|
11
|
+
"output",
|
|
12
|
+
"content",
|
|
13
|
+
"text",
|
|
14
|
+
"result",
|
|
15
|
+
"stdout",
|
|
16
|
+
"aggregated",
|
|
17
|
+
];
|
|
18
|
+
const METADATA_KEYS = new Set([
|
|
19
|
+
"ok",
|
|
20
|
+
"status",
|
|
21
|
+
"success",
|
|
22
|
+
"isError",
|
|
23
|
+
"server",
|
|
24
|
+
"tool",
|
|
25
|
+
"name",
|
|
26
|
+
]);
|
|
27
|
+
const STRUCTURAL_SIBLINGS = new Set([
|
|
28
|
+
"path",
|
|
29
|
+
"command",
|
|
30
|
+
"query",
|
|
31
|
+
"file",
|
|
32
|
+
"url",
|
|
33
|
+
"pattern",
|
|
34
|
+
"target",
|
|
35
|
+
"locations",
|
|
36
|
+
]);
|
|
37
|
+
const RUNNER_TOOL_NAMES = new Set([
|
|
38
|
+
"bash",
|
|
39
|
+
"sh",
|
|
40
|
+
"shell",
|
|
41
|
+
"exec",
|
|
42
|
+
"command",
|
|
43
|
+
"terminal",
|
|
44
|
+
"run",
|
|
45
|
+
]);
|
|
46
|
+
const MAX_PARSE_DEPTH = 3;
|
|
47
|
+
export function presentToolPayload(value, hint) {
|
|
48
|
+
if (value == null || value === "")
|
|
49
|
+
return undefined;
|
|
50
|
+
const extracted = extractDisplayValue(value, 0);
|
|
51
|
+
if (extracted == null || extracted === "")
|
|
52
|
+
return undefined;
|
|
53
|
+
if (isRecord(extracted) || Array.isArray(extracted)) {
|
|
54
|
+
return { code: JSON.stringify(extracted, null, 2), language: "json" };
|
|
55
|
+
}
|
|
56
|
+
const text = String(extracted);
|
|
57
|
+
if (!text)
|
|
58
|
+
return undefined;
|
|
59
|
+
return { code: text, language: detectTextLanguage(text, hint) };
|
|
60
|
+
}
|
|
61
|
+
export function isOneLineAlert(payload) {
|
|
62
|
+
return payload.language === "plaintext" && !payload.code.includes("\n");
|
|
63
|
+
}
|
|
64
|
+
export function toolCallTarget(input, server) {
|
|
65
|
+
const summary = summarizeToolInput(input);
|
|
66
|
+
return summary || server || undefined;
|
|
67
|
+
}
|
|
68
|
+
export function toolCallStatus(state) {
|
|
69
|
+
if (state === "completed")
|
|
70
|
+
return "complete";
|
|
71
|
+
if (state === "error")
|
|
72
|
+
return "error";
|
|
73
|
+
return "running";
|
|
74
|
+
}
|
|
75
|
+
function extractDisplayValue(value, depth) {
|
|
76
|
+
const parsed = tryParseJson(value);
|
|
77
|
+
if (parsed === undefined)
|
|
78
|
+
return value;
|
|
79
|
+
if (typeof parsed === "string") {
|
|
80
|
+
if (depth + 1 >= MAX_PARSE_DEPTH)
|
|
81
|
+
return parsed;
|
|
82
|
+
return extractDisplayValue(parsed, depth + 1);
|
|
83
|
+
}
|
|
84
|
+
if (Array.isArray(parsed) || !isRecord(parsed))
|
|
85
|
+
return parsed;
|
|
86
|
+
const mcpText = mcpContentText(parsed);
|
|
87
|
+
if (mcpText != null)
|
|
88
|
+
return extractDisplayValue(mcpText, depth + 1);
|
|
89
|
+
const unwrapped = unwrapEnvelope(parsed);
|
|
90
|
+
if (unwrapped !== undefined)
|
|
91
|
+
return extractDisplayValue(unwrapped, depth + 1);
|
|
92
|
+
return parsed;
|
|
93
|
+
}
|
|
94
|
+
function tryParseJson(value) {
|
|
95
|
+
if (typeof value !== "string")
|
|
96
|
+
return value;
|
|
97
|
+
const trimmed = value.trim();
|
|
98
|
+
if (!trimmed)
|
|
99
|
+
return undefined;
|
|
100
|
+
if (!trimmed.startsWith("{") &&
|
|
101
|
+
!trimmed.startsWith("[") &&
|
|
102
|
+
!trimmed.startsWith('"')) {
|
|
103
|
+
return undefined;
|
|
104
|
+
}
|
|
105
|
+
try {
|
|
106
|
+
return JSON.parse(trimmed);
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
return undefined;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
function unwrapEnvelope(record) {
|
|
113
|
+
const keys = Object.keys(record);
|
|
114
|
+
const primary = PRIMARY_KEYS.find((key) => record[key] != null && record[key] !== "");
|
|
115
|
+
if (!primary)
|
|
116
|
+
return undefined;
|
|
117
|
+
const rest = keys.filter((key) => key !== primary);
|
|
118
|
+
if (rest.some((key) => !METADATA_KEYS.has(key)))
|
|
119
|
+
return undefined;
|
|
120
|
+
return record[primary];
|
|
121
|
+
}
|
|
122
|
+
function mcpContentText(record) {
|
|
123
|
+
if (!Array.isArray(record.content) || record.content.length === 0) {
|
|
124
|
+
return undefined;
|
|
125
|
+
}
|
|
126
|
+
const rest = Object.keys(record).filter((key) => key !== "content");
|
|
127
|
+
if (rest.some((key) => STRUCTURAL_SIBLINGS.has(key)))
|
|
128
|
+
return undefined;
|
|
129
|
+
if (rest.some((key) => !METADATA_KEYS.has(key)))
|
|
130
|
+
return undefined;
|
|
131
|
+
const parts = record.content.flatMap((entry) => {
|
|
132
|
+
if (typeof entry === "string" && entry)
|
|
133
|
+
return [entry];
|
|
134
|
+
if (isRecord(entry) && typeof entry.text === "string" && entry.text) {
|
|
135
|
+
return [entry.text];
|
|
136
|
+
}
|
|
137
|
+
return [];
|
|
138
|
+
});
|
|
139
|
+
return parts.length > 0 ? parts.join("\n") : undefined;
|
|
140
|
+
}
|
|
141
|
+
function detectTextLanguage(text, hint) {
|
|
142
|
+
if (isRunnerToolName(hint?.toolName))
|
|
143
|
+
return "bash";
|
|
144
|
+
if (hasCommandInput(hint?.input))
|
|
145
|
+
return "bash";
|
|
146
|
+
if (text.includes("\n"))
|
|
147
|
+
return "bash";
|
|
148
|
+
if (looksLikeCli(text))
|
|
149
|
+
return "bash";
|
|
150
|
+
return "plaintext";
|
|
151
|
+
}
|
|
152
|
+
function isRunnerToolName(name) {
|
|
153
|
+
if (!name)
|
|
154
|
+
return false;
|
|
155
|
+
const normalized = name.trim().toLowerCase();
|
|
156
|
+
if (RUNNER_TOOL_NAMES.has(normalized))
|
|
157
|
+
return true;
|
|
158
|
+
const leaf = normalized.split(/[:/]/u).at(-1);
|
|
159
|
+
return leaf != null && RUNNER_TOOL_NAMES.has(leaf);
|
|
160
|
+
}
|
|
161
|
+
function hasCommandInput(input) {
|
|
162
|
+
if (!input)
|
|
163
|
+
return false;
|
|
164
|
+
try {
|
|
165
|
+
const parsed = JSON.parse(input);
|
|
166
|
+
return (isRecord(parsed) &&
|
|
167
|
+
typeof parsed.command === "string" &&
|
|
168
|
+
parsed.command.trim() !== "");
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
return false;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
function looksLikeCli(text) {
|
|
175
|
+
const trimmed = text.trim();
|
|
176
|
+
return (/^[$%] /u.test(trimmed) ||
|
|
177
|
+
/^error:/imu.test(trimmed) ||
|
|
178
|
+
/\b(?:stderr|exit \d+)\b/iu.test(trimmed) ||
|
|
179
|
+
/\|/.test(trimmed));
|
|
180
|
+
}
|
|
181
|
+
function summarizeToolInput(input) {
|
|
182
|
+
if (!input)
|
|
183
|
+
return undefined;
|
|
184
|
+
try {
|
|
185
|
+
const parsed = JSON.parse(input);
|
|
186
|
+
if (typeof parsed === "string" && parsed.trim())
|
|
187
|
+
return parsed.trim();
|
|
188
|
+
if (!isRecord(parsed))
|
|
189
|
+
return undefined;
|
|
190
|
+
for (const key of SUMMARY_KEYS) {
|
|
191
|
+
const value = parsed[key];
|
|
192
|
+
if (typeof value === "string" && value.trim())
|
|
193
|
+
return value.trim();
|
|
194
|
+
}
|
|
195
|
+
const locations = parsed.locations;
|
|
196
|
+
if (Array.isArray(locations)) {
|
|
197
|
+
const first = locations[0];
|
|
198
|
+
if (isRecord(first) && typeof first.path === "string" && first.path) {
|
|
199
|
+
return first.path;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
catch {
|
|
204
|
+
const line = input.trim().split("\n")[0] ?? "";
|
|
205
|
+
if (!line)
|
|
206
|
+
return undefined;
|
|
207
|
+
return line.length > 80 ? `${line.slice(0, 77)}…` : line;
|
|
208
|
+
}
|
|
209
|
+
return undefined;
|
|
210
|
+
}
|
|
211
|
+
function isRecord(value) {
|
|
212
|
+
return value != null && typeof value === "object" && !Array.isArray(value);
|
|
213
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare function isGenericToolName(name: string | undefined): boolean;
|
|
2
|
+
export declare function isEmptyToolInput(value: unknown): boolean;
|
|
3
|
+
export declare function preferToolName(current: string | undefined, incoming: string | undefined): string;
|
|
4
|
+
export declare function toolNameFromInput(input: unknown): string | undefined;
|