@jataware/beaker-client 2.0.0-b.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -0
- package/dist/extension.d.ts +21 -0
- package/dist/extension.js +3 -0
- package/dist/history.d.ts +39 -0
- package/dist/history.js +16 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +10 -0
- package/dist/notebook.d.ts +192 -0
- package/dist/notebook.js +690 -0
- package/dist/render.d.ts +38 -0
- package/dist/render.js +84 -0
- package/dist/session.d.ts +166 -0
- package/dist/session.js +418 -0
- package/dist/util.d.ts +50 -0
- package/dist/util.js +112 -0
- package/package.json +39 -0
- package/src/extension.ts +34 -0
- package/src/history.ts +61 -0
- package/src/index.ts +12 -0
- package/src/notebook.ts +949 -0
- package/src/render.ts +121 -0
- package/src/session.ts +504 -0
- package/src/util.ts +173 -0
package/dist/render.d.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { IRenderMime } from '@jupyterlab/rendermime';
|
|
2
|
+
import { PartialJSONObject } from '@lumino/coreutils';
|
|
3
|
+
export interface IBeakerRendererOptions {
|
|
4
|
+
renderers: ReadonlyArray<IMimeRenderer>;
|
|
5
|
+
}
|
|
6
|
+
export type MimetypeString = "text/plain" | "text/html" | string;
|
|
7
|
+
/**
|
|
8
|
+
*
|
|
9
|
+
*/
|
|
10
|
+
export interface IMimeBundle {
|
|
11
|
+
[mimetype: MimetypeString]: PartialJSONObject;
|
|
12
|
+
}
|
|
13
|
+
export interface IMimeRenderer<OutputType = HTMLElement> {
|
|
14
|
+
rank: number;
|
|
15
|
+
mimetypes: MimetypeString[];
|
|
16
|
+
render: (mimeType: MimetypeString, data: PartialJSONObject, metadata: PartialJSONObject) => OutputType;
|
|
17
|
+
}
|
|
18
|
+
export declare class MimeRenderer implements IMimeRenderer<HTMLElement> {
|
|
19
|
+
rank: number;
|
|
20
|
+
mimetypes: string[];
|
|
21
|
+
render(mimeType: MimetypeString, data: PartialJSONObject, metadata: PartialJSONObject): HTMLElement;
|
|
22
|
+
}
|
|
23
|
+
export declare class JupyterMimeRenderer extends MimeRenderer {
|
|
24
|
+
constructor(factory: IRenderMime.IRendererFactory);
|
|
25
|
+
render(mimeType: MimetypeString, data: PartialJSONObject, metadata?: PartialJSONObject): HTMLElement;
|
|
26
|
+
private _factory;
|
|
27
|
+
}
|
|
28
|
+
export declare class BeakerRenderer {
|
|
29
|
+
constructor(options?: IBeakerRendererOptions);
|
|
30
|
+
addRenderer(renderer: IMimeRenderer): void;
|
|
31
|
+
get rankedMimetypes(): MimetypeString[];
|
|
32
|
+
render(mimeType: MimetypeString, data: PartialJSONObject, metadata?: PartialJSONObject): any;
|
|
33
|
+
renderMimeBundle(bundle: IMimeBundle, metadata?: PartialJSONObject): {
|
|
34
|
+
[key: MimetypeString]: HTMLElement;
|
|
35
|
+
};
|
|
36
|
+
rankedMimetypesInBundle(bundle: IMimeBundle): MimetypeString[];
|
|
37
|
+
private _renderers;
|
|
38
|
+
}
|
package/dist/render.js
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { MimeModel, standardRendererFactories } from '@jupyterlab/rendermime';
|
|
2
|
+
import { Sanitizer } from '@jupyterlab/apputils';
|
|
3
|
+
|
|
4
|
+
class MimeRenderer {
|
|
5
|
+
rank = 100;
|
|
6
|
+
mimetypes = [];
|
|
7
|
+
render(mimeType, data, metadata) {
|
|
8
|
+
return new HTMLElement();
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
class JupyterMimeRenderer extends MimeRenderer {
|
|
12
|
+
constructor(factory) {
|
|
13
|
+
super();
|
|
14
|
+
this._factory = factory;
|
|
15
|
+
this.rank = factory.defaultRank || 100;
|
|
16
|
+
this.mimetypes = [...factory.mimeTypes];
|
|
17
|
+
}
|
|
18
|
+
render(mimeType, data, metadata) {
|
|
19
|
+
const renderer = this._factory.createRenderer({
|
|
20
|
+
mimeType,
|
|
21
|
+
resolver: null,
|
|
22
|
+
sanitizer: new Sanitizer(),
|
|
23
|
+
linkHandler: null,
|
|
24
|
+
latexTypesetter: null,
|
|
25
|
+
markdownParser: null,
|
|
26
|
+
translator: void 0
|
|
27
|
+
});
|
|
28
|
+
const model = new MimeModel({
|
|
29
|
+
trusted: true,
|
|
30
|
+
data: { [mimeType]: data },
|
|
31
|
+
metadata
|
|
32
|
+
});
|
|
33
|
+
renderer.renderModel(model);
|
|
34
|
+
return renderer.node;
|
|
35
|
+
}
|
|
36
|
+
_factory;
|
|
37
|
+
}
|
|
38
|
+
class BeakerRenderer {
|
|
39
|
+
constructor(options) {
|
|
40
|
+
this._renderers = {};
|
|
41
|
+
for (const factory of standardRendererFactories) {
|
|
42
|
+
const renderer = new JupyterMimeRenderer(factory);
|
|
43
|
+
this.addRenderer(renderer);
|
|
44
|
+
}
|
|
45
|
+
for (const renderer of options?.renderers || []) {
|
|
46
|
+
this.addRenderer(renderer);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
addRenderer(renderer) {
|
|
50
|
+
for (const mimetype of renderer.mimetypes) {
|
|
51
|
+
if (!Object.keys(this._renderers).includes(mimetype)) {
|
|
52
|
+
this._renderers[mimetype] = renderer;
|
|
53
|
+
} else {
|
|
54
|
+
const prev_renderer = this._renderers[mimetype];
|
|
55
|
+
if (renderer.rank <= prev_renderer.rank) {
|
|
56
|
+
this._renderers[mimetype] = renderer;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
get rankedMimetypes() {
|
|
62
|
+
const mimetypes = Object.keys(this._renderers);
|
|
63
|
+
mimetypes.sort((a, b) => this._renderers[a].rank - this._renderers[b].rank);
|
|
64
|
+
return mimetypes;
|
|
65
|
+
}
|
|
66
|
+
render(mimeType, data, metadata) {
|
|
67
|
+
const renderer = this._renderers[mimeType];
|
|
68
|
+
if (renderer) {
|
|
69
|
+
return renderer.render(mimeType, data, metadata || {});
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
renderMimeBundle(bundle, metadata) {
|
|
73
|
+
return Object.fromEntries(Object.entries(bundle).map(([mimeType, content]) => {
|
|
74
|
+
return [mimeType, this.render(mimeType, content, metadata)];
|
|
75
|
+
}));
|
|
76
|
+
}
|
|
77
|
+
rankedMimetypesInBundle(bundle) {
|
|
78
|
+
const result = this.rankedMimetypes.filter((mime) => bundle && Object.keys(bundle).includes(mime));
|
|
79
|
+
return result;
|
|
80
|
+
}
|
|
81
|
+
_renderers;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export { BeakerRenderer, JupyterMimeRenderer, MimeRenderer };
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { SessionContext } from '@jupyterlab/apputils';
|
|
2
|
+
import { IKernelConnection } from '@jupyterlab/services/lib/kernel/kernel';
|
|
3
|
+
import { ServiceManager } from '@jupyterlab/services';
|
|
4
|
+
import { JSONObject } from '@lumino/coreutils';
|
|
5
|
+
import { Slot } from '@lumino/signaling';
|
|
6
|
+
import { IBeakerAvailableContexts, IBeakerFuture, IActiveContextInfo } from './util';
|
|
7
|
+
import { BeakerNotebook, BeakerRawCell, BeakerCodeCell, BeakerMarkdownCell, BeakerQueryCell } from './notebook';
|
|
8
|
+
import { BeakerRenderer, IBeakerRendererOptions } from './render';
|
|
9
|
+
import * as messages from '@jupyterlab/services/lib/kernel/messages';
|
|
10
|
+
export interface IBeakerSessionOptions {
|
|
11
|
+
settings: any;
|
|
12
|
+
name: string;
|
|
13
|
+
kernelName?: string;
|
|
14
|
+
sessionId?: string;
|
|
15
|
+
rendererOptions?: IBeakerRendererOptions;
|
|
16
|
+
messageHandler?: Slot<any, any>;
|
|
17
|
+
context?: {
|
|
18
|
+
slug: string;
|
|
19
|
+
payload: any;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
export type JupyterKernelStatus = messages.Status;
|
|
23
|
+
export type BeakerKernelStatus = JupyterKernelStatus | 'connected' | 'connecting' | 'reconnecting' | 'disconnected';
|
|
24
|
+
/**
|
|
25
|
+
* Main class for connecting to and working with a Beaker kernel.
|
|
26
|
+
*/
|
|
27
|
+
export declare class BeakerSession {
|
|
28
|
+
constructor(options?: IBeakerSessionOptions);
|
|
29
|
+
/**
|
|
30
|
+
* Internal initialization logic once all the services are up and ready.
|
|
31
|
+
*/
|
|
32
|
+
private initialize;
|
|
33
|
+
/**
|
|
34
|
+
* Low-level method for reconnecting to the kernel.
|
|
35
|
+
*
|
|
36
|
+
*/
|
|
37
|
+
reconnect(): Promise<SessionContext>;
|
|
38
|
+
/**
|
|
39
|
+
* Low-level method for sending a message to the Beaker kernel over the "shell" channel.
|
|
40
|
+
*
|
|
41
|
+
* @param messageType - The message type, as passed in `msg.header.msg_type`
|
|
42
|
+
* @param content - Any JSON-encodable payload to be included with the message
|
|
43
|
+
* @param messageId - (Optional) Pre-defined id for the message. One will be generated if not provided.
|
|
44
|
+
*/
|
|
45
|
+
sendBeakerMessage(messageType: string, content: JSONObject, messageId?: string, metadata?: {
|
|
46
|
+
[key: string]: any;
|
|
47
|
+
}): IBeakerFuture;
|
|
48
|
+
/**
|
|
49
|
+
* Handler for session-specific messages from the Beaker kernel.
|
|
50
|
+
* This handler will be evoked for all IOPub messages, but should ignore all messages that are not session-specific.
|
|
51
|
+
*
|
|
52
|
+
* @param _sessionContext - The session Context related to the incoming message
|
|
53
|
+
* @param msg - The incoming IOPub message
|
|
54
|
+
*/
|
|
55
|
+
private _sessionMessageHandler;
|
|
56
|
+
private _connectionFailureHandler;
|
|
57
|
+
/**
|
|
58
|
+
* Returns a promise, that once resolved provides all Beaker contexts available in the session.
|
|
59
|
+
*/
|
|
60
|
+
availableContexts(): Promise<IBeakerAvailableContexts>;
|
|
61
|
+
/**
|
|
62
|
+
* Returns a promise that once resolved provides detailed information about the active context.
|
|
63
|
+
*/
|
|
64
|
+
activeContext(): Promise<IActiveContextInfo>;
|
|
65
|
+
setContext(contextPayload: any): Promise<IActiveContextInfo>;
|
|
66
|
+
/**
|
|
67
|
+
* Executes a Beaker Action, handling all of the message
|
|
68
|
+
*
|
|
69
|
+
* The usual IBeakerFuture response handlers can be applied to the returned future to do act upon the responses.
|
|
70
|
+
*
|
|
71
|
+
* @param actionName - Name of the action to execute
|
|
72
|
+
* @param payload - Payload to pass along with the action
|
|
73
|
+
* @param messageId - (Optional) Id for request message. If not provided, will be generated automatically.
|
|
74
|
+
* @returns - A future
|
|
75
|
+
*/
|
|
76
|
+
executeAction(actionName: string, payload: JSONObject, messageId?: string): IBeakerFuture;
|
|
77
|
+
/**
|
|
78
|
+
* Interrupt the kernel activity, stopping execution in both the beaker LLM ReAct loop and the subkernel as needed.
|
|
79
|
+
* See
|
|
80
|
+
*
|
|
81
|
+
* @returns - A future
|
|
82
|
+
*/
|
|
83
|
+
interrupt(): Promise<any>;
|
|
84
|
+
/**
|
|
85
|
+
*
|
|
86
|
+
* @param source - The `code` contents of the cell.
|
|
87
|
+
* @param metadata - (Optional) Any metadata to be associated with the cell.
|
|
88
|
+
* @param outputs - (Optional) Any outputs that should be included/displayed.
|
|
89
|
+
* @returns - A reference to the generated cell
|
|
90
|
+
*/
|
|
91
|
+
addCodeCell(source: string, metadata?: {}, outputs?: never[]): BeakerCodeCell;
|
|
92
|
+
/**
|
|
93
|
+
* Convenience method for adding a MarkdownCell to the notebook
|
|
94
|
+
*
|
|
95
|
+
* @param source - The raw markdown encoded text that should be rendered upon execute
|
|
96
|
+
* @param metadata - (Optional) Any metadata to be associated with the cell.
|
|
97
|
+
* @returns - A reference to the generated cell
|
|
98
|
+
*/
|
|
99
|
+
addMarkdownCell(source: string, metadata?: {}): BeakerMarkdownCell;
|
|
100
|
+
/**
|
|
101
|
+
* Convenience method for adding a RawCell to the notebook
|
|
102
|
+
*
|
|
103
|
+
* @param source - The raw contents to be included in the raw cell.
|
|
104
|
+
* @param metadata - (Optional) Any metadata to be associated with the cell.
|
|
105
|
+
* @returns - A reference to the generated cell
|
|
106
|
+
*/
|
|
107
|
+
addRawCell(source: string, metadata?: {}): BeakerRawCell;
|
|
108
|
+
/**
|
|
109
|
+
* Convenience method for adding a QueryCell to the notebook
|
|
110
|
+
*
|
|
111
|
+
* @param source - The contents of the query for the LLM as a plain string
|
|
112
|
+
* @param metadata - (Optional) Any metadata to be associated with the cell.
|
|
113
|
+
* @returns - A reference to the generated cell
|
|
114
|
+
*/
|
|
115
|
+
addQueryCell(source: string, metadata?: {}): BeakerQueryCell;
|
|
116
|
+
/**
|
|
117
|
+
* Populates the sessions notebook with the provided notebook json
|
|
118
|
+
*
|
|
119
|
+
* @param notebookJSONObject - The json representation of a notebook, as found inside an .ipynb file
|
|
120
|
+
*/
|
|
121
|
+
loadNotebook(notebookJSONObject: object): void;
|
|
122
|
+
/**
|
|
123
|
+
* Completely resets the session, clearing the notebook and history, and restarting the fresh kernel so it is in a fresh state.
|
|
124
|
+
*/
|
|
125
|
+
reset(): void;
|
|
126
|
+
/**
|
|
127
|
+
* A promise that resolves once everything the session requires are also ready.
|
|
128
|
+
*/
|
|
129
|
+
get sessionReady(): Promise<void>;
|
|
130
|
+
/**
|
|
131
|
+
* A reference to the underlying Jupyter SessionContext for this Beaker Session.
|
|
132
|
+
*/
|
|
133
|
+
get session(): SessionContext;
|
|
134
|
+
/**
|
|
135
|
+
* Returns the status of the Beaker kernel
|
|
136
|
+
*/
|
|
137
|
+
get status(): BeakerKernelStatus;
|
|
138
|
+
/**
|
|
139
|
+
* A reference to the Jupyter KernelConnection object for this session.
|
|
140
|
+
*/
|
|
141
|
+
get kernel(): IKernelConnection | null;
|
|
142
|
+
get kernelInfo(): any;
|
|
143
|
+
get lastKernelModel(): any;
|
|
144
|
+
get prevClientId(): string | undefined;
|
|
145
|
+
/**
|
|
146
|
+
* A reference to the Jupyter ServiceManager which contains all of the services for this session.
|
|
147
|
+
*/
|
|
148
|
+
get services(): ServiceManager;
|
|
149
|
+
get renderer(): BeakerRenderer;
|
|
150
|
+
get sessionId(): string;
|
|
151
|
+
private _initialized;
|
|
152
|
+
private _sessionId;
|
|
153
|
+
private _sessionOptions?;
|
|
154
|
+
private _services;
|
|
155
|
+
private _serverSettings;
|
|
156
|
+
private _sessionContext;
|
|
157
|
+
private _messageHandler?;
|
|
158
|
+
private _history;
|
|
159
|
+
private _sessionInfo;
|
|
160
|
+
private _renderer;
|
|
161
|
+
private _kernelInfo;
|
|
162
|
+
private _lastKernelModel?;
|
|
163
|
+
private _prevClientId?;
|
|
164
|
+
private _hasBeenConnected;
|
|
165
|
+
notebook: BeakerNotebook;
|
|
166
|
+
}
|
package/dist/session.js
ADDED
|
@@ -0,0 +1,418 @@
|
|
|
1
|
+
import { SessionContext } from '@jupyterlab/apputils';
|
|
2
|
+
import { ServerConnection } from '@jupyterlab/services/lib/serverconnection';
|
|
3
|
+
import { ServiceManager } from '@jupyterlab/services';
|
|
4
|
+
import * as messages from '@jupyterlab/services/lib/kernel/messages';
|
|
5
|
+
import { v4 } from 'uuid';
|
|
6
|
+
import { createMessageId } from './util.js';
|
|
7
|
+
import { BeakerNotebook, BeakerCodeCell, BeakerMarkdownCell, BeakerRawCell, BeakerQueryCell } from './notebook.js';
|
|
8
|
+
import { BeakerHistory } from './history.js';
|
|
9
|
+
import { BeakerRenderer } from './render.js';
|
|
10
|
+
|
|
11
|
+
class BeakerSession {
|
|
12
|
+
constructor(options) {
|
|
13
|
+
this._sessionId = options?.sessionId ?? v4();
|
|
14
|
+
this._sessionOptions = options;
|
|
15
|
+
this._serverSettings = ServerConnection.makeSettings(options?.settings);
|
|
16
|
+
this._services = new ServiceManager({
|
|
17
|
+
serverSettings: this._serverSettings
|
|
18
|
+
});
|
|
19
|
+
this._hasBeenConnected = false;
|
|
20
|
+
this._services.connectionFailure.connect(this._connectionFailureHandler);
|
|
21
|
+
this._renderer = new BeakerRenderer(options?.rendererOptions);
|
|
22
|
+
this._history = new BeakerHistory(this._sessionId);
|
|
23
|
+
this.notebook = new BeakerNotebook();
|
|
24
|
+
this._initialized = new Promise(async (resolve, reject) => {
|
|
25
|
+
this._services.ready.then(async () => {
|
|
26
|
+
await this.initialize(options);
|
|
27
|
+
if (options?.context) {
|
|
28
|
+
const active_context = await this.activeContext();
|
|
29
|
+
if (active_context.slug !== options.context.slug || JSON.stringify(active_context.config) !== JSON.stringify(options.context.payload)) {
|
|
30
|
+
await this.setContext({
|
|
31
|
+
context: options.context.slug,
|
|
32
|
+
context_info: options.context.payload
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
resolve();
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Internal initialization logic once all the services are up and ready.
|
|
42
|
+
*/
|
|
43
|
+
async initialize(options) {
|
|
44
|
+
this._sessionContext = new SessionContext({
|
|
45
|
+
sessionManager: this._services.sessions,
|
|
46
|
+
specsManager: this._services.kernelspecs,
|
|
47
|
+
name: options?.name,
|
|
48
|
+
path: options?.sessionId,
|
|
49
|
+
kernelPreference: options?.kernelName ? {
|
|
50
|
+
name: options?.kernelName
|
|
51
|
+
} : void 0
|
|
52
|
+
});
|
|
53
|
+
this._sessionContext.kernelChanged.connect((sender, { oldValue, newValue, name }) => {
|
|
54
|
+
oldValue?.anyMessage.disconnect(this._sessionMessageHandler, this);
|
|
55
|
+
newValue?.anyMessage.disconnect(this._sessionMessageHandler, this);
|
|
56
|
+
newValue?.anyMessage.connect(this._sessionMessageHandler, this);
|
|
57
|
+
if (newValue) {
|
|
58
|
+
this._lastKernelModel = newValue?.model;
|
|
59
|
+
this._prevClientId = newValue?.clientId;
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
this._sessionContext.connectionStatusChanged.connect((sender, status) => {
|
|
63
|
+
if (!this._hasBeenConnected && status == "connected") {
|
|
64
|
+
this._hasBeenConnected = true;
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
await this._sessionContext.initialize();
|
|
68
|
+
await this._sessionContext.ready;
|
|
69
|
+
if (options?.messageHandler) {
|
|
70
|
+
this._messageHandler = options.messageHandler;
|
|
71
|
+
this._sessionContext.iopubMessage.connect(this._messageHandler);
|
|
72
|
+
} else {
|
|
73
|
+
this._messageHandler = void 0;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Low-level method for reconnecting to the kernel.
|
|
78
|
+
*
|
|
79
|
+
*/
|
|
80
|
+
async reconnect() {
|
|
81
|
+
this._sessionContext.connectionStatusChanged.emit("connecting");
|
|
82
|
+
this._sessionContext.dispose;
|
|
83
|
+
await this.initialize(this._sessionOptions);
|
|
84
|
+
return this._sessionContext;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Low-level method for sending a message to the Beaker kernel over the "shell" channel.
|
|
88
|
+
*
|
|
89
|
+
* @param messageType - The message type, as passed in `msg.header.msg_type`
|
|
90
|
+
* @param content - Any JSON-encodable payload to be included with the message
|
|
91
|
+
* @param messageId - (Optional) Pre-defined id for the message. One will be generated if not provided.
|
|
92
|
+
*/
|
|
93
|
+
sendBeakerMessage(messageType, content, messageId, metadata) {
|
|
94
|
+
if (!messageId) {
|
|
95
|
+
messageId = createMessageId(messageType);
|
|
96
|
+
}
|
|
97
|
+
if (!this.kernel) {
|
|
98
|
+
throw Error("Unable to send message. Not connected to kernel.");
|
|
99
|
+
}
|
|
100
|
+
const msg = messages.createMessage({
|
|
101
|
+
session: this.session.session?.id || this.kernel?.clientId,
|
|
102
|
+
channel: "shell",
|
|
103
|
+
msgType: messageType,
|
|
104
|
+
content,
|
|
105
|
+
msgId: messageId,
|
|
106
|
+
metadata
|
|
107
|
+
});
|
|
108
|
+
const future = this.kernel.sendShellMessage(
|
|
109
|
+
msg,
|
|
110
|
+
true,
|
|
111
|
+
true
|
|
112
|
+
);
|
|
113
|
+
future.msgId = messageId;
|
|
114
|
+
return future;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Handler for session-specific messages from the Beaker kernel.
|
|
118
|
+
* This handler will be evoked for all IOPub messages, but should ignore all messages that are not session-specific.
|
|
119
|
+
*
|
|
120
|
+
* @param _sessionContext - The session Context related to the incoming message
|
|
121
|
+
* @param msg - The incoming IOPub message
|
|
122
|
+
*/
|
|
123
|
+
_sessionMessageHandler(kernel, { msg, direction }) {
|
|
124
|
+
if (msg.header.msg_type === "context_setup_response" || msg.header.msg_type === "context_info_response") {
|
|
125
|
+
if (msg.header.msg_type === "context_setup_response") {
|
|
126
|
+
this._sessionInfo = msg.content;
|
|
127
|
+
} else if (msg.header.msg_type === "context_info_response") {
|
|
128
|
+
this._sessionInfo = msg.content.info;
|
|
129
|
+
}
|
|
130
|
+
this.notebook.setSubkernelInfo(this._sessionInfo);
|
|
131
|
+
} else if (msg.header.msg_type === "kernel_info_reply") {
|
|
132
|
+
this._kernelInfo = msg.content;
|
|
133
|
+
} else if (msg.header.msg_type === "notebook_state_request") {
|
|
134
|
+
const outboundMsg = messages.createMessage({
|
|
135
|
+
session: kernel.clientId,
|
|
136
|
+
channel: "shell",
|
|
137
|
+
msgType: "notebook_state_response",
|
|
138
|
+
content: this.notebook.toIPynb(),
|
|
139
|
+
msgId: msg.header.msg_id + "_reply",
|
|
140
|
+
metadata: {}
|
|
141
|
+
});
|
|
142
|
+
kernel.sendShellMessage(
|
|
143
|
+
outboundMsg,
|
|
144
|
+
false,
|
|
145
|
+
true
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
_connectionFailureHandler(serviceManager, error) {
|
|
150
|
+
console.log("CONNECTION ERROR:", typeof error);
|
|
151
|
+
console.log({ cause: error.cause, message: error.message, name: error.name, stack: error.stack });
|
|
152
|
+
console.error(error);
|
|
153
|
+
console.error();
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Returns a promise, that once resolved provides all Beaker contexts available in the session.
|
|
157
|
+
*/
|
|
158
|
+
async availableContexts() {
|
|
159
|
+
return new Promise(async (resolve) => {
|
|
160
|
+
`${this._serverSettings.baseUrl}contexts`;
|
|
161
|
+
const response = await fetch(`${this._serverSettings.baseUrl}contexts`);
|
|
162
|
+
const data = await response.json();
|
|
163
|
+
resolve(data);
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Returns a promise that once resolved provides detailed information about the active context.
|
|
168
|
+
*/
|
|
169
|
+
async activeContext() {
|
|
170
|
+
return new Promise(async (resolve, reject) => {
|
|
171
|
+
await this.sessionReady;
|
|
172
|
+
const future = this.sendBeakerMessage(
|
|
173
|
+
"context_info_request",
|
|
174
|
+
{}
|
|
175
|
+
);
|
|
176
|
+
if (future !== void 0) {
|
|
177
|
+
future.onIOPub = async (msg) => {
|
|
178
|
+
if (msg.header.msg_type === "context_info_response") {
|
|
179
|
+
resolve({
|
|
180
|
+
...msg.content,
|
|
181
|
+
kernelInfo: await this.kernel?.info
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
await future.done;
|
|
186
|
+
}
|
|
187
|
+
reject({});
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
async setContext(contextPayload) {
|
|
191
|
+
return new Promise(async (resolve, reject) => {
|
|
192
|
+
const setupResult = this.sendBeakerMessage(
|
|
193
|
+
"context_setup_request",
|
|
194
|
+
contextPayload
|
|
195
|
+
);
|
|
196
|
+
if (setupResult) {
|
|
197
|
+
await setupResult.done;
|
|
198
|
+
const contextInfo = setupResult.msg.content;
|
|
199
|
+
const kernelInfo = await this.kernel?.requestKernelInfo();
|
|
200
|
+
resolve({
|
|
201
|
+
...contextInfo,
|
|
202
|
+
kernelInfo: kernelInfo?.content
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
reject({});
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Executes a Beaker Action, handling all of the message
|
|
210
|
+
*
|
|
211
|
+
* The usual IBeakerFuture response handlers can be applied to the returned future to do act upon the responses.
|
|
212
|
+
*
|
|
213
|
+
* @param actionName - Name of the action to execute
|
|
214
|
+
* @param payload - Payload to pass along with the action
|
|
215
|
+
* @param messageId - (Optional) Id for request message. If not provided, will be generated automatically.
|
|
216
|
+
* @returns - A future
|
|
217
|
+
*/
|
|
218
|
+
executeAction(actionName, payload, messageId) {
|
|
219
|
+
const requestType = `${actionName}_request`;
|
|
220
|
+
const responseType = `${actionName}_response`;
|
|
221
|
+
const messageFuture = this.sendBeakerMessage(
|
|
222
|
+
requestType,
|
|
223
|
+
payload,
|
|
224
|
+
messageId
|
|
225
|
+
);
|
|
226
|
+
if (messageFuture) {
|
|
227
|
+
const responseHandler = async (msg) => {
|
|
228
|
+
if (msg.header.msg_type === responseType && messageFuture.onResponse) {
|
|
229
|
+
await messageFuture.onResponse(msg);
|
|
230
|
+
} else if (msg.header.msg_type === "code_cell") {
|
|
231
|
+
const nb = this.notebook;
|
|
232
|
+
const codeCell = new BeakerCodeCell({
|
|
233
|
+
cell_type: "code",
|
|
234
|
+
source: msg.content.code,
|
|
235
|
+
metadata: {},
|
|
236
|
+
outputs: []
|
|
237
|
+
});
|
|
238
|
+
nb.addCell(codeCell);
|
|
239
|
+
}
|
|
240
|
+
return true;
|
|
241
|
+
};
|
|
242
|
+
messageFuture.registerMessageHook(responseHandler);
|
|
243
|
+
}
|
|
244
|
+
return messageFuture;
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Interrupt the kernel activity, stopping execution in both the beaker LLM ReAct loop and the subkernel as needed.
|
|
248
|
+
* See
|
|
249
|
+
*
|
|
250
|
+
* @returns - A future
|
|
251
|
+
*/
|
|
252
|
+
interrupt() {
|
|
253
|
+
if (this.session.session?.kernel) {
|
|
254
|
+
return this.session.session.kernel.interrupt();
|
|
255
|
+
} else {
|
|
256
|
+
return new Promise(() => {
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
*
|
|
262
|
+
* @param source - The `code` contents of the cell.
|
|
263
|
+
* @param metadata - (Optional) Any metadata to be associated with the cell.
|
|
264
|
+
* @param outputs - (Optional) Any outputs that should be included/displayed.
|
|
265
|
+
* @returns - A reference to the generated cell
|
|
266
|
+
*/
|
|
267
|
+
addCodeCell(source, metadata = {}, outputs = []) {
|
|
268
|
+
const cell = new BeakerCodeCell({
|
|
269
|
+
cell_type: "code",
|
|
270
|
+
source,
|
|
271
|
+
metadata,
|
|
272
|
+
outputs
|
|
273
|
+
});
|
|
274
|
+
this.notebook.addCell(cell);
|
|
275
|
+
return cell;
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Convenience method for adding a MarkdownCell to the notebook
|
|
279
|
+
*
|
|
280
|
+
* @param source - The raw markdown encoded text that should be rendered upon execute
|
|
281
|
+
* @param metadata - (Optional) Any metadata to be associated with the cell.
|
|
282
|
+
* @returns - A reference to the generated cell
|
|
283
|
+
*/
|
|
284
|
+
addMarkdownCell(source, metadata = {}) {
|
|
285
|
+
const cell = new BeakerMarkdownCell({
|
|
286
|
+
cell_type: "markdown",
|
|
287
|
+
source,
|
|
288
|
+
metadata
|
|
289
|
+
});
|
|
290
|
+
this.notebook.addCell(cell);
|
|
291
|
+
return cell;
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Convenience method for adding a RawCell to the notebook
|
|
295
|
+
*
|
|
296
|
+
* @param source - The raw contents to be included in the raw cell.
|
|
297
|
+
* @param metadata - (Optional) Any metadata to be associated with the cell.
|
|
298
|
+
* @returns - A reference to the generated cell
|
|
299
|
+
*/
|
|
300
|
+
addRawCell(source, metadata = {}) {
|
|
301
|
+
const cell = new BeakerRawCell({
|
|
302
|
+
cell_type: "raw",
|
|
303
|
+
source,
|
|
304
|
+
metadata
|
|
305
|
+
});
|
|
306
|
+
this.notebook.addCell(cell);
|
|
307
|
+
return cell;
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Convenience method for adding a QueryCell to the notebook
|
|
311
|
+
*
|
|
312
|
+
* @param source - The contents of the query for the LLM as a plain string
|
|
313
|
+
* @param metadata - (Optional) Any metadata to be associated with the cell.
|
|
314
|
+
* @returns - A reference to the generated cell
|
|
315
|
+
*/
|
|
316
|
+
addQueryCell(source, metadata = {}) {
|
|
317
|
+
const cell = new BeakerQueryCell({
|
|
318
|
+
cell_type: "query",
|
|
319
|
+
source,
|
|
320
|
+
metadata
|
|
321
|
+
});
|
|
322
|
+
this.notebook.addCell(cell);
|
|
323
|
+
return cell;
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Populates the sessions notebook with the provided notebook json
|
|
327
|
+
*
|
|
328
|
+
* @param notebookJSONObject - The json representation of a notebook, as found inside an .ipynb file
|
|
329
|
+
*/
|
|
330
|
+
loadNotebook(notebookJSONObject) {
|
|
331
|
+
this.notebook.loadFromIPynb(notebookJSONObject);
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Completely resets the session, clearing the notebook and history, and restarting the fresh kernel so it is in a fresh state.
|
|
335
|
+
*/
|
|
336
|
+
reset() {
|
|
337
|
+
this.notebook.cells.splice(0, this.notebook.cells.length);
|
|
338
|
+
this._history.clear();
|
|
339
|
+
this._sessionContext.restartKernel();
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* A promise that resolves once everything the session requires are also ready.
|
|
343
|
+
*/
|
|
344
|
+
get sessionReady() {
|
|
345
|
+
return new Promise(async (resolve) => {
|
|
346
|
+
await this._services.ready;
|
|
347
|
+
await this._sessionContext.ready;
|
|
348
|
+
await this._initialized;
|
|
349
|
+
resolve();
|
|
350
|
+
});
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* A reference to the underlying Jupyter SessionContext for this Beaker Session.
|
|
354
|
+
*/
|
|
355
|
+
get session() {
|
|
356
|
+
return this._sessionContext;
|
|
357
|
+
}
|
|
358
|
+
/**
|
|
359
|
+
* Returns the status of the Beaker kernel
|
|
360
|
+
*/
|
|
361
|
+
get status() {
|
|
362
|
+
const connectionStatus = this.kernel?.connectionStatus;
|
|
363
|
+
const kernelStatus = this.kernel?.status;
|
|
364
|
+
if (connectionStatus === "connected" && kernelStatus) {
|
|
365
|
+
return kernelStatus;
|
|
366
|
+
} else if (connectionStatus === "connecting" && this._hasBeenConnected) {
|
|
367
|
+
return "reconnecting";
|
|
368
|
+
} else if (connectionStatus) {
|
|
369
|
+
return connectionStatus || "unknown";
|
|
370
|
+
} else {
|
|
371
|
+
return "disconnected";
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
/**
|
|
375
|
+
* A reference to the Jupyter KernelConnection object for this session.
|
|
376
|
+
*/
|
|
377
|
+
get kernel() {
|
|
378
|
+
return this._sessionContext?.session?.kernel || null;
|
|
379
|
+
}
|
|
380
|
+
get kernelInfo() {
|
|
381
|
+
return this._kernelInfo;
|
|
382
|
+
}
|
|
383
|
+
get lastKernelModel() {
|
|
384
|
+
return this._lastKernelModel;
|
|
385
|
+
}
|
|
386
|
+
get prevClientId() {
|
|
387
|
+
return this._prevClientId;
|
|
388
|
+
}
|
|
389
|
+
/**
|
|
390
|
+
* A reference to the Jupyter ServiceManager which contains all of the services for this session.
|
|
391
|
+
*/
|
|
392
|
+
get services() {
|
|
393
|
+
return this._services;
|
|
394
|
+
}
|
|
395
|
+
get renderer() {
|
|
396
|
+
return this._renderer;
|
|
397
|
+
}
|
|
398
|
+
get sessionId() {
|
|
399
|
+
return this._sessionContext.path;
|
|
400
|
+
}
|
|
401
|
+
_initialized;
|
|
402
|
+
_sessionId;
|
|
403
|
+
_sessionOptions;
|
|
404
|
+
_services;
|
|
405
|
+
_serverSettings;
|
|
406
|
+
_sessionContext;
|
|
407
|
+
_messageHandler;
|
|
408
|
+
_history;
|
|
409
|
+
_sessionInfo;
|
|
410
|
+
_renderer;
|
|
411
|
+
_kernelInfo;
|
|
412
|
+
_lastKernelModel;
|
|
413
|
+
_prevClientId;
|
|
414
|
+
_hasBeenConnected;
|
|
415
|
+
notebook;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
export { BeakerSession };
|