@oceanum/oceanumlab 4.6.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 (83) hide show
  1. package/LICENSE +29 -0
  2. package/README.md +116 -0
  3. package/lib/DatameshUI.d.ts +5 -0
  4. package/lib/DatameshUI.js +8 -0
  5. package/lib/DatameshUI.js.map +1 -0
  6. package/lib/DatameshWidget.d.ts +59 -0
  7. package/lib/DatameshWidget.js +573 -0
  8. package/lib/DatameshWidget.js.map +1 -0
  9. package/lib/DatasourceItem.d.ts +12 -0
  10. package/lib/DatasourceItem.js +47 -0
  11. package/lib/DatasourceItem.js.map +1 -0
  12. package/lib/aiLoop.d.ts +60 -0
  13. package/lib/aiLoop.js +85 -0
  14. package/lib/aiLoop.js.map +1 -0
  15. package/lib/chatRouter.d.ts +64 -0
  16. package/lib/chatRouter.js +225 -0
  17. package/lib/chatRouter.js.map +1 -0
  18. package/lib/constants.d.ts +14 -0
  19. package/lib/constants.js +15 -0
  20. package/lib/constants.js.map +1 -0
  21. package/lib/conversationPin.d.ts +68 -0
  22. package/lib/conversationPin.js +120 -0
  23. package/lib/conversationPin.js.map +1 -0
  24. package/lib/handler.d.ts +8 -0
  25. package/lib/handler.js +36 -0
  26. package/lib/handler.js.map +1 -0
  27. package/lib/index.d.ts +16 -0
  28. package/lib/index.js +273 -0
  29. package/lib/index.js.map +1 -0
  30. package/lib/kernelHandoff.d.ts +61 -0
  31. package/lib/kernelHandoff.js +236 -0
  32. package/lib/kernelHandoff.js.map +1 -0
  33. package/lib/notebookContext.d.ts +48 -0
  34. package/lib/notebookContext.js +118 -0
  35. package/lib/notebookContext.js.map +1 -0
  36. package/lib/notebookHost.d.ts +6 -0
  37. package/lib/notebookHost.js +72 -0
  38. package/lib/notebookHost.js.map +1 -0
  39. package/lib/notebookRun.d.ts +37 -0
  40. package/lib/notebookRun.js +70 -0
  41. package/lib/notebookRun.js.map +1 -0
  42. package/lib/progress.d.ts +43 -0
  43. package/lib/progress.js +103 -0
  44. package/lib/progress.js.map +1 -0
  45. package/lib/sse.d.ts +26 -0
  46. package/lib/sse.js +112 -0
  47. package/lib/sse.js.map +1 -0
  48. package/package.json +151 -0
  49. package/schema/datamesh-connect.json +35 -0
  50. package/src/DatameshUI.tsx +15 -0
  51. package/src/DatameshWidget.tsx +909 -0
  52. package/src/DatasourceItem.tsx +124 -0
  53. package/src/__tests__/aiLoop.spec.ts +304 -0
  54. package/src/__tests__/chatRouter.spec.ts +315 -0
  55. package/src/__tests__/conversationPin.spec.ts +236 -0
  56. package/src/__tests__/kernelHandoff.spec.ts +106 -0
  57. package/src/__tests__/notebookContext.spec.ts +97 -0
  58. package/src/__tests__/notebookHost.spec.ts +195 -0
  59. package/src/__tests__/notebookRun.spec.ts +95 -0
  60. package/src/__tests__/notebookSnapshot.spec.ts +62 -0
  61. package/src/__tests__/oceanumlab.spec.ts +9 -0
  62. package/src/__tests__/sse.spec.ts +304 -0
  63. package/src/aiLoop.ts +140 -0
  64. package/src/chatRouter.ts +329 -0
  65. package/src/constants.ts +16 -0
  66. package/src/conversationPin.ts +148 -0
  67. package/src/global.d.ts +5 -0
  68. package/src/handler.ts +46 -0
  69. package/src/index.ts +327 -0
  70. package/src/kernelHandoff.ts +284 -0
  71. package/src/notebookContext.ts +144 -0
  72. package/src/notebookHost.ts +97 -0
  73. package/src/notebookRun.ts +104 -0
  74. package/src/progress.ts +121 -0
  75. package/src/sse.ts +127 -0
  76. package/src/svg.d.ts +4 -0
  77. package/style/base.css +5 -0
  78. package/style/icons/oceanum-dark.svg +1 -0
  79. package/style/icons/oceanum-light.svg +1 -0
  80. package/style/icons/oceanum.png +0 -0
  81. package/style/icons/oceanum.svg +1 -0
  82. package/style/index.css +477 -0
  83. package/style/index.js +1 -0
@@ -0,0 +1,120 @@
1
+ /**
2
+ * The notebook the current conversation lives in: what the agent is shown,
3
+ * and where its answers go.
4
+ *
5
+ * Pinned when the conversation starts -- New chat, or the first message after
6
+ * the panel opens -- to the notebook in the ACTIVE TAB or, when that tab is
7
+ * not a notebook, to a new notebook made the active tab. Kept for the whole
8
+ * conversation: switching tabs does not move it, a rename is followed, and a
9
+ * pinned notebook that has been closed is opened again when an answer has
10
+ * cells to place in it. The active tab rather than the tracker's current
11
+ * notebook, which is the LAST-FOCUSED notebook even with a terminal or a text
12
+ * file in front.
13
+ */
14
+ export class ConversationPin {
15
+ constructor(_host) {
16
+ this._host = _host;
17
+ this._panel = null;
18
+ // Kept separately so a closed notebook can be found again.
19
+ this._path = null;
20
+ this._started = false;
21
+ // Starting, re-opening and creating happen one at a time: a second New chat
22
+ // must find the notebook the first one created as the active tab rather
23
+ // than create another.
24
+ this._queue = Promise.resolve();
25
+ }
26
+ /** Start a new conversation. Resolves to its notebook's name. */
27
+ start() {
28
+ return this._serial(() => this._startNow());
29
+ }
30
+ /**
31
+ * Start the conversation if nothing has, and report its notebook's name
32
+ * either way.
33
+ */
34
+ ensure() {
35
+ return this._serial(async () => this._started ? this.name() : this._startNow());
36
+ }
37
+ /**
38
+ * The conversation's notebook if it is open, starting the conversation if
39
+ * nothing has -- but NOT opening a closed one again: that is for placing an
40
+ * answer, not for asking a question. See path() for reading a closed one.
41
+ */
42
+ current() {
43
+ return this._serial(async () => {
44
+ if (!this._started) {
45
+ await this._startNow();
46
+ }
47
+ return this._live();
48
+ });
49
+ }
50
+ /**
51
+ * The conversation's notebook, opened again if it has been closed. When it
52
+ * cannot be -- deleted, or gone some other way -- a new notebook takes its
53
+ * place, so the conversation always has one. Null only if none can be made.
54
+ */
55
+ notebook() {
56
+ return this._serial(async () => {
57
+ if (!this._started) {
58
+ await this._startNow();
59
+ }
60
+ const live = this._live();
61
+ if (live) {
62
+ return live;
63
+ }
64
+ const reopened = this._path ? await this._host.reopen(this._path) : null;
65
+ this._pin(reopened !== null && reopened !== void 0 ? reopened : (await this._host.create()));
66
+ return this._panel;
67
+ });
68
+ }
69
+ /** The conversation's notebook, brought to the front: see notebook(). */
70
+ async show() {
71
+ const panel = await this.notebook();
72
+ if (panel) {
73
+ this._host.activate(panel);
74
+ }
75
+ return panel;
76
+ }
77
+ /** Where the notebook's file is -- its last known place while it is closed. */
78
+ path() {
79
+ return this._path;
80
+ }
81
+ /** The notebook's name -- its last known one while it is closed. */
82
+ name() {
83
+ var _a;
84
+ const live = this._live();
85
+ if (live) {
86
+ return live.title.label;
87
+ }
88
+ return this._path ? ((_a = this._path.split('/').pop()) !== null && _a !== void 0 ? _a : this._path) : null;
89
+ }
90
+ _live() {
91
+ return this._panel && !this._panel.isDisposed ? this._panel : null;
92
+ }
93
+ async _startNow() {
94
+ var _a;
95
+ this._pin((_a = this._host.activeTab()) !== null && _a !== void 0 ? _a : (await this._host.create()));
96
+ this._started = true;
97
+ return this.name();
98
+ }
99
+ _pin(panel) {
100
+ var _a, _b;
101
+ (_a = this._panel) === null || _a === void 0 ? void 0 : _a.context.pathChanged.disconnect(this._onPathChanged, this);
102
+ this._panel = panel;
103
+ this._path = (_b = panel === null || panel === void 0 ? void 0 : panel.context.path) !== null && _b !== void 0 ? _b : null;
104
+ // Follows a rename or move made while it is open, so that a notebook
105
+ // renamed and then closed is found again under its new name.
106
+ panel === null || panel === void 0 ? void 0 : panel.context.pathChanged.connect(this._onPathChanged, this);
107
+ }
108
+ _onPathChanged(_, path) {
109
+ this._path = path;
110
+ }
111
+ _serial(task) {
112
+ const run = this._queue.then(task);
113
+ // A failed step is reported to its caller; it must not block the next.
114
+ this._queue = run.catch(() => {
115
+ /* swallowed here only */
116
+ });
117
+ return run;
118
+ }
119
+ }
120
+ //# sourceMappingURL=conversationPin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conversationPin.js","sourceRoot":"","sources":["../src/conversationPin.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Call the API extension
3
+ *
4
+ * @param endPoint API REST end point for the extension
5
+ * @param init Initial values for the request
6
+ * @returns The response body interpreted as JSON
7
+ */
8
+ export declare function requestAPI<T>(endPoint?: string, init?: RequestInit): Promise<T>;
package/lib/handler.js ADDED
@@ -0,0 +1,36 @@
1
+ import { URLExt } from '@jupyterlab/coreutils';
2
+ import { ServerConnection } from '@jupyterlab/services';
3
+ /**
4
+ * Call the API extension
5
+ *
6
+ * @param endPoint API REST end point for the extension
7
+ * @param init Initial values for the request
8
+ * @returns The response body interpreted as JSON
9
+ */
10
+ export async function requestAPI(endPoint = '', init = {}) {
11
+ // Make request to Jupyter API
12
+ const settings = ServerConnection.makeSettings();
13
+ const requestUrl = URLExt.join(settings.baseUrl, 'oceanum', // API Namespace
14
+ endPoint);
15
+ let response;
16
+ try {
17
+ response = await ServerConnection.makeRequest(requestUrl, init, settings);
18
+ }
19
+ catch (error) {
20
+ throw new ServerConnection.NetworkError(error);
21
+ }
22
+ let data = await response.text();
23
+ if (data.length > 0) {
24
+ try {
25
+ data = JSON.parse(data);
26
+ }
27
+ catch (error) {
28
+ console.log('Not a JSON response body.', response);
29
+ }
30
+ }
31
+ if (!response.ok) {
32
+ throw new ServerConnection.ResponseError(response, data.message || data);
33
+ }
34
+ return data;
35
+ }
36
+ //# sourceMappingURL=handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handler.js","sourceRoot":"","sources":["../src/handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAE/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAExD;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,QAAQ,GAAG,EAAE,EACb,OAAoB,EAAE;IAEtB,8BAA8B;IAC9B,MAAM,QAAQ,GAAG,gBAAgB,CAAC,YAAY,EAAE,CAAC;IACjD,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAC5B,QAAQ,CAAC,OAAO,EAChB,SAAS,EAAE,gBAAgB;IAC3B,QAAQ,CACT,CAAC;IAEF,IAAI,QAAkB,CAAC;IACvB,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,gBAAgB,CAAC,WAAW,CAAC,UAAU,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;IAC5E,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,gBAAgB,CAAC,YAAY,CAAC,KAAY,CAAC,CAAC;IACxD,CAAC;IAED,IAAI,IAAI,GAAQ,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IAEtC,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpB,IAAI,CAAC;YACH,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC1B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,GAAG,CAAC,2BAA2B,EAAE,QAAQ,CAAC,CAAC;QACrD,CAAC;IACH,CAAC;IAED,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,gBAAgB,CAAC,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,CAAC;IAC3E,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
package/lib/index.d.ts ADDED
@@ -0,0 +1,16 @@
1
+ import { JupyterFrontEndPlugin } from '@jupyterlab/application';
2
+ import { LabIcon } from '@jupyterlab/ui-components';
3
+ import '../style/index.css';
4
+ export declare const oceanumIcon: LabIcon;
5
+ /**
6
+ * Initialization data for the extension.
7
+ */
8
+ export declare const datamesh_connect_extension: JupyterFrontEndPlugin<void>;
9
+ /**
10
+ * Second plugin: Oceanum AI chat integration.
11
+ * Wires ChatRouter → KernelHandoff and exposes the
12
+ * `oceanum-ai:submit-prompt` command.
13
+ */
14
+ export declare const oceanum_ai_extension: JupyterFrontEndPlugin<void>;
15
+ declare const _default: JupyterFrontEndPlugin<void>[];
16
+ export default _default;
package/lib/index.js ADDED
@@ -0,0 +1,273 @@
1
+ import { ILayoutRestorer, ILabStatus } from '@jupyterlab/application';
2
+ import { ICommandPalette, Notification } from '@jupyterlab/apputils';
3
+ import { LabIcon } from '@jupyterlab/ui-components';
4
+ import { find } from '@lumino/algorithm';
5
+ import { ISettingRegistry } from '@jupyterlab/settingregistry';
6
+ import { IStateDB } from '@jupyterlab/statedb';
7
+ import { INotebookTracker } from '@jupyterlab/notebook';
8
+ import { DatameshConnectWidget } from './DatameshWidget';
9
+ import { DatameshUI } from './DatameshUI';
10
+ import { requestAPI } from './handler';
11
+ import { ChatRouter, ChatRouterError } from './chatRouter';
12
+ import { reporterFor } from './progress';
13
+ import { ConversationPin } from './conversationPin';
14
+ import { snapshotFromIpynb, snapshotOf } from './notebookContext';
15
+ import { notebookHost } from './notebookHost';
16
+ import { KernelHandoff } from './kernelHandoff';
17
+ import { runChatLoop, STOPPED } from './aiLoop';
18
+ import { MAX_OBSERVE_ROUNDS } from './constants';
19
+ import '../style/index.css';
20
+ import oceanumSvg from '../style/icons/oceanum.svg';
21
+ // Theme-adaptive icon using currentColor (auto-adapts to light/dark themes)
22
+ export const oceanumIcon = new LabIcon({
23
+ name: 'oceanum:icon',
24
+ svgstr: oceanumSvg
25
+ });
26
+ const PLUGIN_ID = '@oceanum/oceanumlab:datamesh-connect';
27
+ /**
28
+ * Initialization data for the extension.
29
+ */
30
+ export const datamesh_connect_extension = {
31
+ id: PLUGIN_ID,
32
+ autoStart: true,
33
+ requires: [
34
+ ICommandPalette,
35
+ ILayoutRestorer,
36
+ ILabStatus,
37
+ ISettingRegistry,
38
+ IStateDB
39
+ ],
40
+ activate: (app, palette, restorer, status, settingRegistry) => {
41
+ console.log('Oceanum datamesh connect extension is loaded');
42
+ //Try to get the datamesh token from the settings
43
+ const updateSettings = (set) => {
44
+ const token = set.get('datameshToken');
45
+ if (token && token.user) {
46
+ window.datameshToken = token.user;
47
+ requestAPI('env/', {
48
+ method: 'POST',
49
+ body: JSON.stringify({ DATAMESH_TOKEN: token.user })
50
+ }).then(res => console.log(res));
51
+ }
52
+ window.injectToken = set.get('injectToken').user;
53
+ };
54
+ //Try to get the datamesh token from the envars
55
+ Promise.all([app.restored, settingRegistry.load(PLUGIN_ID)])
56
+ .then(([, setting]) => {
57
+ // Read the settings
58
+ updateSettings(setting);
59
+ // Listen for your plugin setting changes using Signal
60
+ setting.changed.connect(updateSettings);
61
+ })
62
+ .catch(reason => {
63
+ console.error(`Something went wrong when reading the Oceanumlab settings.\n${reason}`);
64
+ });
65
+ const getCurrentWidget = () => {
66
+ return app.shell.currentWidget;
67
+ };
68
+ const openDatameshUI = (event) => {
69
+ const widgetId = 'datamesh-ui';
70
+ const openWidget = find(app.shell.widgets('main'), (widget, index) => {
71
+ return widget.id === widgetId;
72
+ });
73
+ if (openWidget) {
74
+ app.shell.activateById(widgetId);
75
+ return;
76
+ }
77
+ const datameshUIWidget = new DatameshUI();
78
+ datameshUIWidget.title.label = 'Oceanum Datamesh';
79
+ datameshUIWidget.id = widgetId;
80
+ datameshUIWidget.title.closable = true;
81
+ datameshUIWidget.title.icon = oceanumIcon;
82
+ datameshUIWidget.addClass('datamesh-ui');
83
+ app.shell.add(datameshUIWidget, 'main');
84
+ };
85
+ const datameshConnectWidget = new DatameshConnectWidget({
86
+ app,
87
+ name: 'Datamesh Connect',
88
+ icon: oceanumIcon,
89
+ openDatameshUI: openDatameshUI,
90
+ commands: app.commands,
91
+ getCurrentWidget
92
+ });
93
+ datameshConnectWidget.id = 'datamesh-connect';
94
+ datameshConnectWidget.title.icon = oceanumIcon;
95
+ datameshConnectWidget.title.caption = 'Datamesh Connect';
96
+ restorer.add(datameshConnectWidget, 'datamesh-connect');
97
+ // Rank has been chosen somewhat arbitrarily to give priority to the running
98
+ // sessions widget in the sidebar.
99
+ app.shell.add(datameshConnectWidget, 'left', { rank: 900 });
100
+ app.commands.addCommand('datamesh-ui:open', {
101
+ execute: (args) => {
102
+ openDatameshUI(args);
103
+ }
104
+ });
105
+ }
106
+ };
107
+ /**
108
+ * Second plugin: Oceanum AI chat integration.
109
+ * Wires ChatRouter → KernelHandoff and exposes the
110
+ * `oceanum-ai:submit-prompt` command.
111
+ */
112
+ export const oceanum_ai_extension = {
113
+ id: '@oceanum/oceanumlab:ai-chat',
114
+ autoStart: true,
115
+ requires: [INotebookTracker, ISettingRegistry],
116
+ activate: (app, notebookTracker, settingRegistry) => {
117
+ console.log('Oceanum AI chat extension is loaded');
118
+ const SETTINGS_ID = '@oceanum/oceanumlab:datamesh-connect';
119
+ settingRegistry
120
+ .load(SETTINGS_ID)
121
+ .then(settings => {
122
+ // The notebook the current conversation lives in: what the agent is
123
+ // shown, and where its answers go.
124
+ const pin = new ConversationPin(notebookHost(app, notebookTracker));
125
+ // What a request carries from the conversation's notebook. An open
126
+ // notebook is read as it stands; a closed one is read from its file
127
+ // rather than opened again, which is left for an answer that has
128
+ // cells to place.
129
+ // The panel the current request read its selected cell from, if the
130
+ // notebook was open: a code answer may replace that cell only there.
131
+ let readFrom = null;
132
+ const router = new ChatRouter(settings, async () => {
133
+ const open = await pin.current();
134
+ readFrom = open;
135
+ if (open) {
136
+ return snapshotOf(open.content);
137
+ }
138
+ const path = pin.path();
139
+ if (!path) {
140
+ return null;
141
+ }
142
+ try {
143
+ const file = await app.serviceManager.contents.get(path, {
144
+ content: true
145
+ });
146
+ return snapshotFromIpynb(file.content);
147
+ }
148
+ catch (_a) {
149
+ // Gone: an answer's cells will go into a new notebook instead.
150
+ return null;
151
+ }
152
+ });
153
+ // Asked only when an answer has blocks to place: brings the
154
+ // conversation's notebook to the front, opening it again if closed.
155
+ const handoff = new KernelHandoff(() => pin.show(), () => readFrom);
156
+ // The run in flight, if any. Command args must be JSON, so a signal
157
+ // cannot be passed in; Stop is a second command that reaches it here.
158
+ let current = null;
159
+ app.commands.addCommand('oceanum-ai:stop', {
160
+ label: 'Stop the current Oceanum AI response',
161
+ execute: () => {
162
+ current === null || current === void 0 ? void 0 : current.abort();
163
+ }
164
+ });
165
+ app.commands.addCommand('oceanum-ai:new-chat', {
166
+ label: 'Start a new Oceanum AI chat',
167
+ execute: () => {
168
+ // The run in flight belongs to the conversation being thrown away:
169
+ // stop it placing anything more. The panel discards its result.
170
+ // It stops being the current run now, not once it has finished
171
+ // unwinding, so it cannot report progress into the new chat.
172
+ const run = current;
173
+ current = null;
174
+ run === null || run === void 0 ? void 0 : run.abort();
175
+ return pin.start();
176
+ }
177
+ });
178
+ app.commands.addCommand('oceanum-ai:chat-context', {
179
+ label: 'The notebook the current Oceanum AI chat is about',
180
+ // Starts the conversation if nothing has -- so the first message of
181
+ // one nobody started with New chat pins the same way -- and reports
182
+ // its notebook either way.
183
+ execute: () => pin.ensure()
184
+ });
185
+ app.commands.addCommand('oceanum-ai:submit-prompt', {
186
+ label: 'Submit prompt to Oceanum AI',
187
+ execute: async (args) => {
188
+ var _a;
189
+ const prompt = args['prompt'];
190
+ const chatHistory = (_a = args['chatHistory']) !== null && _a !== void 0 ? _a : [];
191
+ if (!prompt) {
192
+ return;
193
+ }
194
+ // A caller that skipped 'oceanum-ai:chat-context' still gets a
195
+ // conversation pinned the same way.
196
+ await pin.ensure();
197
+ // Read per prompt, not once at load, so a settings change applies
198
+ // to the next question without a reload.
199
+ const autoRunCode = settings.get('autoRunCode')
200
+ .composite;
201
+ const iterate = settings.get('iterate').composite;
202
+ current === null || current === void 0 ? void 0 : current.abort();
203
+ const controller = new AbortController();
204
+ current = controller;
205
+ // This run's progress, heard only while it is the current run.
206
+ const report = reporterFor(() => current === controller);
207
+ try {
208
+ // Cleared in the `finally` below however this ends, so the last
209
+ // phase does not sit on screen after the answer has arrived --
210
+ // or after Stop.
211
+ return await runChatLoop(prompt, chatHistory, {
212
+ route: (p, h, signal) => router.route(p, h, signal, report),
213
+ observe: (p, h, runs, signal) => {
214
+ // The agent's turn again: the notebook's "Running the
215
+ // code…" must not stay up while the agent reads what the
216
+ // code printed.
217
+ report({ phase: 'interpreting' });
218
+ return router.observe(p, h, runs, signal, report);
219
+ },
220
+ place: (response, opts) => {
221
+ // The notebook's turn, not the agent's. Without this the
222
+ // last phase the AGENT reported stays on screen while a
223
+ // cell is running, so the user is told the agent is
224
+ // reading dataset details when what is actually happening
225
+ // is their own code executing. That is a worse claim than
226
+ // the "Thinking…" it replaced, which was vague rather than
227
+ // wrong. And "running" only when there is code that will.
228
+ if (response.blocks.length > 0) {
229
+ const runsCode = autoRunCode &&
230
+ response.blocks.some(block => block.type === 'code' && block.content.trim());
231
+ report({ phase: runsCode ? 'running' : 'placing' });
232
+ }
233
+ return handoff.inject(response, opts);
234
+ }
235
+ }, {
236
+ autoRunCode,
237
+ iterate,
238
+ maxRounds: MAX_OBSERVE_ROUNDS,
239
+ signal: controller.signal
240
+ });
241
+ }
242
+ catch (err) {
243
+ // Anything that failed because the user pressed Stop is not an
244
+ // error to them: the aborted fetch, or its body read.
245
+ if (controller.signal.aborted) {
246
+ return STOPPED;
247
+ }
248
+ if (err instanceof ChatRouterError) {
249
+ Notification.error(err.message, { autoClose: 5000 });
250
+ }
251
+ else {
252
+ console.error('Oceanum AI: unexpected error', err);
253
+ }
254
+ }
255
+ finally {
256
+ // However this ended -- answered, failed, or stopped -- the
257
+ // agent is no longer doing anything, so the last phase must not
258
+ // sit on screen claiming otherwise.
259
+ report(null);
260
+ if (current === controller) {
261
+ current = null;
262
+ }
263
+ }
264
+ }
265
+ });
266
+ })
267
+ .catch(reason => {
268
+ console.error(`Oceanum AI: could not load settings from ${SETTINGS_ID}.\n${reason}`);
269
+ });
270
+ }
271
+ };
272
+ export default [datamesh_connect_extension, oceanum_ai_extension];
273
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,61 @@
1
+ import { NotebookPanel } from '@jupyterlab/notebook';
2
+ import { OceanumResponse } from './chatRouter';
3
+ import type { PlacedResponse } from './aiLoop';
4
+ export interface InjectOptions {
5
+ /** If true, replace the selected code cell instead of inserting a new one */
6
+ replaceCodeCell?: boolean;
7
+ /** Run each code cell as it is placed. A user setting, not a build constant. */
8
+ autoRun?: boolean;
9
+ /**
10
+ * Stop. Once aborted, no further block is placed or run, and a cell that is
11
+ * executing is interrupted -- the kernel is the half of a round that an
12
+ * aborted fetch cannot reach.
13
+ */
14
+ signal?: AbortSignal;
15
+ }
16
+ export declare class KernelHandoff {
17
+ private _target;
18
+ private _readFrom;
19
+ /**
20
+ * @param _target The conversation's notebook, brought to the front -- and
21
+ * opened again first, if it was closed. Asked only when there is
22
+ * something to place, so an answer with no blocks leaves the tabs alone.
23
+ * @param _readFrom The panel the request read its selected cell from, if
24
+ * any. A code answer replaces the selected cell only in that same panel:
25
+ * one opened since has some other cell selected, and replacing it would
26
+ * overwrite the user's work.
27
+ */
28
+ constructor(_target: () => Promise<NotebookPanel | null>, _readFrom: () => NotebookPanel | null);
29
+ /**
30
+ * Place every block the response carries, in order, and return the message
31
+ * for the chat window.
32
+ *
33
+ * This used to switch on `response.type`, because a response was exactly one
34
+ * of text, code or markdown. It can now carry any number of blocks in any
35
+ * combination (OCE-173) — a markdown table describing a dataset followed by
36
+ * the query that produced it is one response, not two — so the branch became
37
+ * a loop. No blocks is the commonest case and still touches no notebook.
38
+ */
39
+ inject(response: OceanumResponse, options?: InjectOptions): Promise<PlacedResponse>;
40
+ /**
41
+ * Execute one cell and report what happened, and whether it happened at all.
42
+ *
43
+ * `runCells` resolves false for a kernel error (the traceback is in the
44
+ * outputs) and for some of the ways a cell can fail to execute at all
45
+ * (pending input, interrupted); it resolves TRUE with nothing run when there
46
+ * is no kernel, when the kernel is terminating, or when the kernel is still
47
+ * starting (`CodeCell.execute` bails silently on a session without a
48
+ * kernel); and it rejects when the kernel is dead. None of the did-not-run
49
+ * paths touch the outputs, so a replaced cell would still show its previous
50
+ * run; they are cleared first so that whatever is there afterwards came from
51
+ * this run. The execution count is cleared with them and only a kernel
52
+ * reply sets it again, so a null count afterwards means nothing ran,
53
+ * whatever `runCells` resolved to; that is reported as an error rather than
54
+ * as a clean, silent run.
55
+ *
56
+ * Pending input is refused BEFORE clearing: clearing the outputs of a cell
57
+ * that is waiting on `input()` disposes the prompt widget, and the kernel
58
+ * then waits forever for an answer nobody can give.
59
+ */
60
+ private _run;
61
+ }