@jupyterlite/ai 0.17.0 → 0.19.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.
Files changed (114) hide show
  1. package/lib/chat-commands/clear.d.ts +1 -0
  2. package/lib/chat-commands/index.d.ts +1 -0
  3. package/lib/chat-commands/skills.d.ts +2 -1
  4. package/lib/chat-model-handler.d.ts +4 -3
  5. package/lib/chat-model-handler.js +2 -1
  6. package/lib/chat-model.d.ts +148 -8
  7. package/lib/chat-model.js +368 -79
  8. package/lib/completion/completion-provider.d.ts +3 -1
  9. package/lib/completion/completion-provider.js +1 -2
  10. package/lib/completion/index.d.ts +1 -0
  11. package/lib/components/clear-button.d.ts +1 -0
  12. package/lib/components/clear-button.js +3 -4
  13. package/lib/components/completion-status.d.ts +1 -0
  14. package/lib/components/completion-status.js +5 -4
  15. package/lib/components/index.d.ts +1 -0
  16. package/lib/components/model-select.d.ts +1 -0
  17. package/lib/components/model-select.js +62 -67
  18. package/lib/components/save-button.d.ts +3 -2
  19. package/lib/components/save-button.js +4 -5
  20. package/lib/components/stop-button.d.ts +1 -0
  21. package/lib/components/stop-button.js +3 -4
  22. package/lib/components/tool-select.d.ts +3 -1
  23. package/lib/components/tool-select.js +47 -60
  24. package/lib/components/usage-display.d.ts +4 -2
  25. package/lib/components/usage-display.js +50 -61
  26. package/lib/diff-manager.d.ts +3 -1
  27. package/lib/index.d.ts +3 -2
  28. package/lib/index.js +50 -59
  29. package/lib/models/settings-model.d.ts +3 -1
  30. package/lib/models/settings-model.js +1 -0
  31. package/lib/rendered-message-outputarea.d.ts +1 -0
  32. package/lib/tokens.d.ts +48 -597
  33. package/lib/tokens.js +2 -31
  34. package/lib/widgets/ai-settings.d.ts +3 -1
  35. package/lib/widgets/ai-settings.js +185 -344
  36. package/lib/widgets/main-area-chat.d.ts +3 -3
  37. package/lib/widgets/main-area-chat.js +2 -4
  38. package/lib/widgets/provider-config-dialog.d.ts +2 -1
  39. package/lib/widgets/provider-config-dialog.js +102 -167
  40. package/package.json +111 -258
  41. package/schema/settings-model.json +6 -0
  42. package/src/chat-commands/skills.ts +2 -2
  43. package/src/chat-model-handler.ts +10 -6
  44. package/src/chat-model.ts +488 -96
  45. package/src/completion/completion-provider.ts +6 -6
  46. package/src/components/clear-button.tsx +0 -2
  47. package/src/components/completion-status.tsx +2 -2
  48. package/src/components/model-select.tsx +1 -1
  49. package/src/components/save-button.tsx +3 -3
  50. package/src/components/stop-button.tsx +0 -2
  51. package/src/components/tool-select.tsx +10 -9
  52. package/src/components/usage-display.tsx +4 -2
  53. package/src/diff-manager.ts +4 -3
  54. package/src/index.ts +103 -107
  55. package/src/models/settings-model.ts +7 -6
  56. package/src/tokens.ts +54 -744
  57. package/src/widgets/ai-settings.tsx +40 -11
  58. package/src/widgets/main-area-chat.ts +5 -8
  59. package/src/widgets/provider-config-dialog.tsx +8 -8
  60. package/LICENSE +0 -30
  61. package/README.md +0 -49
  62. package/lib/agent.d.ts +0 -277
  63. package/lib/agent.js +0 -1116
  64. package/lib/icons.d.ts +0 -3
  65. package/lib/icons.js +0 -8
  66. package/lib/providers/built-in-providers.d.ts +0 -21
  67. package/lib/providers/built-in-providers.js +0 -233
  68. package/lib/providers/generated-context-windows.d.ts +0 -8
  69. package/lib/providers/generated-context-windows.js +0 -96
  70. package/lib/providers/model-info.d.ts +0 -3
  71. package/lib/providers/model-info.js +0 -58
  72. package/lib/providers/models.d.ts +0 -37
  73. package/lib/providers/models.js +0 -28
  74. package/lib/providers/provider-registry.d.ts +0 -49
  75. package/lib/providers/provider-registry.js +0 -72
  76. package/lib/providers/provider-tools.d.ts +0 -36
  77. package/lib/providers/provider-tools.js +0 -93
  78. package/lib/skills/index.d.ts +0 -4
  79. package/lib/skills/index.js +0 -7
  80. package/lib/skills/parse-skill.d.ts +0 -25
  81. package/lib/skills/parse-skill.js +0 -69
  82. package/lib/skills/skill-loader.d.ts +0 -25
  83. package/lib/skills/skill-loader.js +0 -133
  84. package/lib/skills/skill-registry.d.ts +0 -31
  85. package/lib/skills/skill-registry.js +0 -100
  86. package/lib/skills/types.d.ts +0 -29
  87. package/lib/skills/types.js +0 -5
  88. package/lib/tools/commands.d.ts +0 -11
  89. package/lib/tools/commands.js +0 -154
  90. package/lib/tools/skills.d.ts +0 -9
  91. package/lib/tools/skills.js +0 -73
  92. package/lib/tools/tool-registry.d.ts +0 -35
  93. package/lib/tools/tool-registry.js +0 -55
  94. package/lib/tools/web.d.ts +0 -8
  95. package/lib/tools/web.js +0 -196
  96. package/src/agent.ts +0 -1441
  97. package/src/icons.ts +0 -11
  98. package/src/providers/built-in-providers.ts +0 -241
  99. package/src/providers/generated-context-windows.ts +0 -102
  100. package/src/providers/model-info.ts +0 -88
  101. package/src/providers/models.ts +0 -76
  102. package/src/providers/provider-registry.ts +0 -88
  103. package/src/providers/provider-tools.ts +0 -179
  104. package/src/skills/index.ts +0 -14
  105. package/src/skills/parse-skill.ts +0 -91
  106. package/src/skills/skill-loader.ts +0 -175
  107. package/src/skills/skill-registry.ts +0 -137
  108. package/src/skills/types.ts +0 -37
  109. package/src/tools/commands.ts +0 -210
  110. package/src/tools/skills.ts +0 -84
  111. package/src/tools/tool-registry.ts +0 -63
  112. package/src/tools/web.ts +0 -238
  113. package/src/types.d.ts +0 -4
  114. package/style/icons/jupyternaut-lite.svg +0 -7
@@ -1,93 +0,0 @@
1
- import { anthropic } from '@ai-sdk/anthropic';
2
- import { openai } from '@ai-sdk/openai';
3
- const DEFAULT_ANTHROPIC_WEB_FETCH_MAX_USES = 2;
4
- const DEFAULT_ANTHROPIC_WEB_FETCH_MAX_CONTENT_TOKENS = 12000;
5
- function normalizeDomain(value) {
6
- const normalized = (value || '').trim().toLowerCase();
7
- const withoutProtocol = normalized.replace(/^https?:\/\//, '');
8
- const hostname = withoutProtocol.split('/')[0].trim();
9
- // Treat "*.example.com" as "example.com" for provider domain filters.
10
- return hostname.startsWith('*.') ? hostname.slice(2) : hostname;
11
- }
12
- function collectDomains(value) {
13
- value = value || [];
14
- const values = Array.from(new Set(value.map(normalizeDomain).filter(domain => domain.length > 0)));
15
- return values;
16
- }
17
- function createOpenAIWebSearchTool(webSearchSettings) {
18
- const allowedDomains = collectDomains(webSearchSettings.allowedDomains);
19
- return openai.tools.webSearch({
20
- externalWebAccess: webSearchSettings.externalWebAccess,
21
- searchContextSize: webSearchSettings.searchContextSize,
22
- filters: allowedDomains.length > 0 ? { allowedDomains } : undefined
23
- });
24
- }
25
- function createAnthropicWebSearchTool(webSearchSettings) {
26
- const allowedDomains = collectDomains(webSearchSettings.allowedDomains);
27
- const blockedDomains = collectDomains(webSearchSettings.blockedDomains);
28
- return anthropic.tools.webSearch_20250305({
29
- maxUses: webSearchSettings.maxUses,
30
- allowedDomains: allowedDomains.length > 0 ? allowedDomains : undefined,
31
- blockedDomains: blockedDomains.length > 0 ? blockedDomains : undefined
32
- });
33
- }
34
- function createAnthropicWebFetchTool(webFetchSettings) {
35
- const maxUses = webFetchSettings.maxUses ?? DEFAULT_ANTHROPIC_WEB_FETCH_MAX_USES;
36
- const maxContentTokens = webFetchSettings.maxContentTokens ??
37
- DEFAULT_ANTHROPIC_WEB_FETCH_MAX_CONTENT_TOKENS;
38
- const allowedDomains = collectDomains(webFetchSettings.allowedDomains);
39
- const blockedDomains = collectDomains(webFetchSettings.blockedDomains);
40
- const citationsEnabled = webFetchSettings.citationsEnabled;
41
- return anthropic.tools.webFetch_20250910({
42
- maxUses,
43
- maxContentTokens,
44
- allowedDomains: allowedDomains.length > 0 ? allowedDomains : undefined,
45
- blockedDomains: blockedDomains.length > 0 ? blockedDomains : undefined,
46
- citations: citationsEnabled !== undefined ? { enabled: citationsEnabled } : undefined
47
- });
48
- }
49
- function createWebSearchTool(implementation, webSearchSettings) {
50
- switch (implementation) {
51
- case 'openai':
52
- return createOpenAIWebSearchTool(webSearchSettings);
53
- case 'anthropic':
54
- return createAnthropicWebSearchTool(webSearchSettings);
55
- default:
56
- throw new Error(`Unsupported web search implementation: ${implementation}`);
57
- }
58
- }
59
- function createWebFetchTool(implementation, webFetchSettings) {
60
- switch (implementation) {
61
- case 'anthropic':
62
- return createAnthropicWebFetchTool(webFetchSettings);
63
- default:
64
- throw new Error(`Unsupported web fetch implementation: ${implementation}`);
65
- }
66
- }
67
- /**
68
- * Create provider-defined tools from custom settings and provider capabilities.
69
- */
70
- export function createProviderTools(options) {
71
- const tools = {};
72
- if (!options.customSettings ||
73
- !options.providerInfo?.providerToolCapabilities) {
74
- return tools;
75
- }
76
- const capabilities = options.providerInfo.providerToolCapabilities;
77
- const webSearchSettings = options.customSettings.webSearch;
78
- const webFetchSettings = options.customSettings.webFetch;
79
- const webSearchEnabled = webSearchSettings?.enabled === true;
80
- const webFetchEnabled = webFetchSettings?.enabled === true;
81
- const webSearchCapability = capabilities.webSearch;
82
- if (webSearchEnabled && webSearchSettings && webSearchCapability) {
83
- const requiresNoFunctionTools = webSearchCapability.requiresNoFunctionTools === true;
84
- if (!requiresNoFunctionTools || !options.hasFunctionTools) {
85
- tools.web_search = createWebSearchTool(webSearchCapability.implementation, webSearchSettings);
86
- }
87
- }
88
- const webFetchCapability = capabilities.webFetch;
89
- if (webFetchEnabled && webFetchSettings && webFetchCapability) {
90
- tools.web_fetch = createWebFetchTool(webFetchCapability.implementation, webFetchSettings);
91
- }
92
- return tools;
93
- }
@@ -1,4 +0,0 @@
1
- export { parseSkillMd, type IParsedSkill } from './parse-skill';
2
- export { loadSkillsFromPaths, type ISkillFileDefinition } from './skill-loader';
3
- export type { ISkillDefinition, ISkillRegistration, ISkillResourceResult, ISkillSummary } from './types';
4
- export { SkillRegistry } from './skill-registry';
@@ -1,7 +0,0 @@
1
- /*
2
- * Copyright (c) Jupyter Development Team.
3
- * Distributed under the terms of the Modified BSD License.
4
- */
5
- export { parseSkillMd } from './parse-skill';
6
- export { loadSkillsFromPaths } from './skill-loader';
7
- export { SkillRegistry } from './skill-registry';
@@ -1,25 +0,0 @@
1
- /**
2
- * Parsed skill definition from a SKILL.md file.
3
- */
4
- export interface IParsedSkill {
5
- name: string;
6
- description: string;
7
- instructions: string;
8
- }
9
- /**
10
- * Parse a SKILL.md file content into a structured skill definition.
11
- *
12
- * Expected format:
13
- * ```
14
- * ---
15
- * name: my-skill
16
- * description: A brief description of the skill
17
- * ---
18
- * Full instructions body here...
19
- * ```
20
- *
21
- * @param content - The raw content of a SKILL.md file
22
- * @returns Parsed skill with name, description, and instructions
23
- * @throws Error if the frontmatter is missing or invalid
24
- */
25
- export declare function parseSkillMd(content: string): IParsedSkill;
@@ -1,69 +0,0 @@
1
- /*
2
- * Copyright (c) Jupyter Development Team.
3
- * Distributed under the terms of the Modified BSD License.
4
- */
5
- import { parse as parseYaml } from 'yaml';
6
- /**
7
- * Parse a SKILL.md file content into a structured skill definition.
8
- *
9
- * Expected format:
10
- * ```
11
- * ---
12
- * name: my-skill
13
- * description: A brief description of the skill
14
- * ---
15
- * Full instructions body here...
16
- * ```
17
- *
18
- * @param content - The raw content of a SKILL.md file
19
- * @returns Parsed skill with name, description, and instructions
20
- * @throws Error if the frontmatter is missing or invalid
21
- */
22
- export function parseSkillMd(content) {
23
- const normalizedContent = content
24
- .replace(/^\uFEFF/, '')
25
- .replace(/\r\n/g, '\n');
26
- const lines = normalizedContent.split('\n');
27
- if (lines[0]?.trim() !== '---') {
28
- throw new Error('Invalid SKILL.md: missing frontmatter delimiters (---)');
29
- }
30
- const frontmatterLines = [];
31
- let i = 1;
32
- for (; i < lines.length; i++) {
33
- const line = lines[i];
34
- const trimmed = line.trim();
35
- if (trimmed === '---') {
36
- break;
37
- }
38
- frontmatterLines.push(line);
39
- }
40
- if (i >= lines.length) {
41
- throw new Error('Invalid SKILL.md: missing frontmatter delimiters (---)');
42
- }
43
- const frontmatter = frontmatterLines.join('\n');
44
- const instructions = lines
45
- .slice(i + 1)
46
- .join('\n')
47
- .trim();
48
- let metadata;
49
- try {
50
- metadata = parseYaml(frontmatter);
51
- }
52
- catch (error) {
53
- throw new Error(`Invalid SKILL.md: YAML frontmatter parse failed: ${error}`);
54
- }
55
- const data = metadata;
56
- const name = data?.name;
57
- const description = data?.description;
58
- if (typeof name !== 'string' || name.trim().length === 0) {
59
- throw new Error('Invalid SKILL.md: missing "name" in frontmatter');
60
- }
61
- if (typeof description !== 'string' || description.trim().length === 0) {
62
- throw new Error('Invalid SKILL.md: missing "description" in frontmatter');
63
- }
64
- return {
65
- name: name.trim(),
66
- description: description.trim(),
67
- instructions
68
- };
69
- }
@@ -1,25 +0,0 @@
1
- import { Contents } from '@jupyterlab/services';
2
- import { IParsedSkill } from './parse-skill';
3
- /**
4
- * A skill definition loaded from the filesystem.
5
- */
6
- export interface ISkillFileDefinition extends IParsedSkill {
7
- /**
8
- * Path to the skill directory (e.g. ".agents/skills/my-skill").
9
- */
10
- path: string;
11
- /**
12
- * Paths to resource files relative to the skill directory.
13
- */
14
- resources: string[];
15
- }
16
- /**
17
- * Load skills from multiple directories. Each path is scanned in order;
18
- * when the same skill name appears in more than one path, the first
19
- * occurrence wins.
20
- *
21
- * @param contentsManager - The Jupyter contents manager
22
- * @param skillsPaths - Ordered list of directories to scan
23
- * @returns Merged array of loaded skill definitions
24
- */
25
- export declare function loadSkillsFromPaths(contentsManager: Contents.IManager, skillsPaths: string[]): Promise<ISkillFileDefinition[]>;
@@ -1,133 +0,0 @@
1
- /*
2
- * Copyright (c) Jupyter Development Team.
3
- * Distributed under the terms of the Modified BSD License.
4
- */
5
- import { PathExt } from '@jupyterlab/coreutils';
6
- import { parseSkillMd } from './parse-skill';
7
- /**
8
- * Load skills from multiple directories. Each path is scanned in order;
9
- * when the same skill name appears in more than one path, the first
10
- * occurrence wins.
11
- *
12
- * @param contentsManager - The Jupyter contents manager
13
- * @param skillsPaths - Ordered list of directories to scan
14
- * @returns Merged array of loaded skill definitions
15
- */
16
- export async function loadSkillsFromPaths(contentsManager, skillsPaths) {
17
- const seen = new Set();
18
- const merged = [];
19
- for (const skillsPath of skillsPaths) {
20
- const skills = await loadSkills(contentsManager, skillsPath);
21
- for (const skill of skills) {
22
- if (seen.has(skill.name)) {
23
- console.debug(`Skipping duplicate skill "${skill.name}" from "${skillsPath}" (already loaded from an earlier path).`);
24
- continue;
25
- }
26
- seen.add(skill.name);
27
- merged.push(skill);
28
- }
29
- }
30
- return merged;
31
- }
32
- /**
33
- * Load skills from the filesystem by scanning a directory for subdirectories
34
- * containing SKILL.md files.
35
- *
36
- * @param contentsManager - The Jupyter contents manager
37
- * @param skillsPath - Path to the skills directory (e.g. ".agents/skills")
38
- * @returns Array of loaded skill definitions
39
- */
40
- async function loadSkills(contentsManager, skillsPath) {
41
- const skills = [];
42
- // Walk each path segment from root to verify the directory exists before fetching it.
43
- const segments = skillsPath.split('/').filter(s => s.length > 0);
44
- let currentPath = '';
45
- for (const segment of segments) {
46
- let listing;
47
- try {
48
- listing = await contentsManager.get(currentPath, { content: true });
49
- }
50
- catch (error) {
51
- console.debug(`Skills path segment not found at "${currentPath}":`, error);
52
- return skills;
53
- }
54
- const children = (listing.content ?? []);
55
- if (!children.some(c => c.type === 'directory' && c.name === segment)) {
56
- return skills;
57
- }
58
- currentPath = PathExt.join(currentPath, segment);
59
- }
60
- const dirModel = await contentsManager.get(skillsPath, { content: true });
61
- if (dirModel.type !== 'directory' || !dirModel.content) {
62
- return skills;
63
- }
64
- for (const child of dirModel.content) {
65
- if (child.type !== 'directory') {
66
- continue;
67
- }
68
- // List the subdirectory to check if SKILL.md exists before requesting it
69
- const subDir = await contentsManager.get(child.path, { content: true });
70
- const subChildren = (subDir.content ?? []);
71
- if (!subChildren.some(f => f.type === 'file' && f.name === 'SKILL.md')) {
72
- continue;
73
- }
74
- const skillMdPath = `${child.path}/SKILL.md`;
75
- const fileModel = await contentsManager.get(skillMdPath, {
76
- content: true
77
- });
78
- if (typeof fileModel.content !== 'string') {
79
- console.warn(`Skipping ${skillMdPath}: content is not a string`);
80
- continue;
81
- }
82
- try {
83
- const parsed = parseSkillMd(fileModel.content);
84
- const resources = await collectResourcePaths(contentsManager, child.path);
85
- skills.push({
86
- ...parsed,
87
- path: child.path,
88
- resources
89
- });
90
- }
91
- catch (error) {
92
- console.warn(`Skipping skill at ${child.path}:`, error);
93
- }
94
- }
95
- return skills;
96
- }
97
- /**
98
- * Recursively collect paths to all resource files in a skill directory,
99
- * excluding `SKILL.md`. Content is loaded on-demand when the agent
100
- * requests a specific resource.
101
- */
102
- async function collectResourcePaths(contentsManager, basePath) {
103
- const resourcePaths = [];
104
- async function walk(dirPath) {
105
- let dirModel;
106
- try {
107
- dirModel = await contentsManager.get(dirPath, { content: true });
108
- }
109
- catch (error) {
110
- console.warn(`Failed to list directory ${dirPath}:`, error);
111
- return;
112
- }
113
- if (dirModel.type !== 'directory' || !dirModel.content) {
114
- return;
115
- }
116
- for (const item of dirModel.content) {
117
- // Skip checkpoint directories
118
- if (item.name === '.ipynb_checkpoints') {
119
- continue;
120
- }
121
- if (item.type === 'directory') {
122
- await walk(item.path);
123
- }
124
- else if (item.type === 'file' && item.name !== 'SKILL.md') {
125
- // Store path relative to the skill directory
126
- const relativePath = PathExt.relative(basePath, item.path);
127
- resourcePaths.push(relativePath);
128
- }
129
- }
130
- }
131
- await walk(basePath);
132
- return resourcePaths;
133
- }
@@ -1,31 +0,0 @@
1
- import { DisposableDelegate } from '@lumino/disposable';
2
- import { ISignal } from '@lumino/signaling';
3
- import { ISkillDefinition, ISkillRegistration, ISkillResourceResult, ISkillSummary } from './types';
4
- import { ISkillRegistry } from '../tokens';
5
- export declare class SkillRegistry implements ISkillRegistry {
6
- /**
7
- * Signal emitted when skills change.
8
- */
9
- get skillsChanged(): ISignal<ISkillRegistry, void>;
10
- /**
11
- * Register a single skill.
12
- */
13
- registerSkill(skill: ISkillRegistration): DisposableDelegate;
14
- /**
15
- * List all registered skills with summary info, optionally filtered by a
16
- * search query (matches name or description, case-insensitive).
17
- */
18
- listSkills(query?: string): ISkillSummary[];
19
- /**
20
- * Get the full definition for a skill.
21
- */
22
- getSkill(name: string): ISkillDefinition | null;
23
- /**
24
- * Load a resource for a skill.
25
- */
26
- getSkillResource(name: string, resource: string): Promise<ISkillResourceResult>;
27
- private _registerSkillInternal;
28
- private _skills;
29
- private _skillsChanged;
30
- private _nextRegistrationId;
31
- }
@@ -1,100 +0,0 @@
1
- /*
2
- * Copyright (c) Jupyter Development Team.
3
- * Distributed under the terms of the Modified BSD License.
4
- */
5
- import { DisposableDelegate } from '@lumino/disposable';
6
- import { Signal } from '@lumino/signaling';
7
- export class SkillRegistry {
8
- /**
9
- * Signal emitted when skills change.
10
- */
11
- get skillsChanged() {
12
- return this._skillsChanged;
13
- }
14
- /**
15
- * Register a single skill.
16
- */
17
- registerSkill(skill) {
18
- const entry = this._registerSkillInternal(skill);
19
- if (!entry) {
20
- return new DisposableDelegate(() => undefined);
21
- }
22
- this._skillsChanged.emit(void 0);
23
- const registrationId = entry.registrationId;
24
- const name = skill.name;
25
- return new DisposableDelegate(() => {
26
- const current = this._skills.get(name);
27
- if (!current || current.registrationId !== registrationId) {
28
- return;
29
- }
30
- this._skills.delete(name);
31
- this._skillsChanged.emit(void 0);
32
- });
33
- }
34
- /**
35
- * List all registered skills with summary info, optionally filtered by a
36
- * search query (matches name or description, case-insensitive).
37
- */
38
- listSkills(query) {
39
- const summaries = [];
40
- for (const entry of this._skills.values()) {
41
- summaries.push({
42
- name: entry.definition.name,
43
- description: entry.definition.description
44
- });
45
- }
46
- summaries.sort((a, b) => a.name.localeCompare(b.name));
47
- if (!query) {
48
- return summaries;
49
- }
50
- const term = query.toLowerCase();
51
- return summaries.filter(skill => skill.name.toLowerCase().includes(term) ||
52
- skill.description.toLowerCase().includes(term));
53
- }
54
- /**
55
- * Get the full definition for a skill.
56
- */
57
- getSkill(name) {
58
- const entry = this._skills.get(name);
59
- return entry ? entry.definition : null;
60
- }
61
- /**
62
- * Load a resource for a skill.
63
- */
64
- async getSkillResource(name, resource) {
65
- const entry = this._skills.get(name);
66
- if (!entry) {
67
- return {
68
- name,
69
- resource,
70
- error: `Skill not found: ${name}`
71
- };
72
- }
73
- if (!entry.loadResource) {
74
- return {
75
- name,
76
- resource,
77
- error: `Skill does not provide resources: ${name}`
78
- };
79
- }
80
- return entry.loadResource(resource);
81
- }
82
- _registerSkillInternal(skill) {
83
- const existing = this._skills.get(skill.name);
84
- if (existing) {
85
- console.warn(`Skipping duplicate skill name "${skill.name}".`);
86
- return null;
87
- }
88
- const { loadResource, ...definition } = skill;
89
- const entry = {
90
- definition,
91
- loadResource,
92
- registrationId: this._nextRegistrationId++
93
- };
94
- this._skills.set(skill.name, entry);
95
- return entry;
96
- }
97
- _skills = new Map();
98
- _skillsChanged = new Signal(this);
99
- _nextRegistrationId = 0;
100
- }
@@ -1,29 +0,0 @@
1
- /**
2
- * Summary information about a skill.
3
- */
4
- export interface ISkillSummary {
5
- name: string;
6
- description: string;
7
- }
8
- /**
9
- * Full skill definition loaded from a SKILL.md file or registry.
10
- */
11
- export interface ISkillDefinition extends ISkillSummary {
12
- instructions: string;
13
- resources: string[];
14
- }
15
- /**
16
- * Result for loading a skill resource.
17
- */
18
- export interface ISkillResourceResult {
19
- name: string;
20
- resource: string;
21
- content?: string;
22
- error?: string;
23
- }
24
- /**
25
- * Skill registration payload for the skill registry.
26
- */
27
- export interface ISkillRegistration extends ISkillDefinition {
28
- loadResource?: (resource: string) => Promise<ISkillResourceResult>;
29
- }
@@ -1,5 +0,0 @@
1
- /*
2
- * Copyright (c) Jupyter Development Team.
3
- * Distributed under the terms of the Modified BSD License.
4
- */
5
- export {};
@@ -1,11 +0,0 @@
1
- import { CommandRegistry } from '@lumino/commands';
2
- import type { IAISettingsModel, ITool } from '../tokens';
3
- /**
4
- * Create a tool to discover all available commands and their metadata
5
- */
6
- export declare function createDiscoverCommandsTool(commands: CommandRegistry): ITool;
7
- /**
8
- * Create a tool to execute a specific JupyterLab command.
9
- * Commands in the settings' commandsRequiringApproval list will need approval.
10
- */
11
- export declare function createExecuteCommandTool(commands: CommandRegistry, settingsModel: IAISettingsModel): ITool;