codebind 0.3.0__tar.gz → 0.4.1__tar.gz
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.
- {codebind-0.3.0 → codebind-0.4.1}/PKG-INFO +15 -4
- {codebind-0.3.0 → codebind-0.4.1}/README.md +13 -3
- codebind-0.4.1/data/share/jupyter/labextensions/codebind-jupyterlab/install.json +5 -0
- codebind-0.4.1/data/share/jupyter/labextensions/codebind-jupyterlab/package.json +37 -0
- codebind-0.4.1/data/share/jupyter/labextensions/codebind-jupyterlab/static/590.6544266cd73a003b.js +1 -0
- codebind-0.4.1/data/share/jupyter/labextensions/codebind-jupyterlab/static/remoteEntry.6f017385dfc989f1.js +1 -0
- codebind-0.4.1/data/share/jupyter/labextensions/codebind-jupyterlab/static/style.js +2 -0
- codebind-0.4.1/data/share/jupyter/labextensions/codebind-jupyterlab/static/third-party-licenses.json +3 -0
- codebind-0.4.1/jupyterlab/.yarnrc.yml +1 -0
- codebind-0.4.1/jupyterlab/install.json +5 -0
- codebind-0.4.1/jupyterlab/package.json +33 -0
- codebind-0.4.1/jupyterlab/src/index.ts +265 -0
- codebind-0.4.1/jupyterlab/tsconfig.json +19 -0
- codebind-0.4.1/jupyterlab/yarn.lock +3789 -0
- {codebind-0.3.0 → codebind-0.4.1}/pyproject.toml +15 -1
- {codebind-0.3.0 → codebind-0.4.1}/pyproject.toml.orig +13 -1
- {codebind-0.3.0 → codebind-0.4.1}/src/codebind/__init__.py +2 -0
- codebind-0.4.1/src/codebind/execution.py +363 -0
- {codebind-0.3.0 → codebind-0.4.1}/src/codebind/extension.py +9 -1
- codebind-0.4.1/src/codebind/jupyter.py +109 -0
- {codebind-0.3.0 → codebind-0.4.1}/src/codebind/session.py +10 -3
- codebind-0.3.0/src/codebind/execution.py +0 -88
- {codebind-0.3.0 → codebind-0.4.1}/LICENSE +0 -0
- {codebind-0.3.0 → codebind-0.4.1}/src/codebind/cli.py +0 -0
- {codebind-0.3.0 → codebind-0.4.1}/src/codebind/display.py +0 -0
- {codebind-0.3.0 → codebind-0.4.1}/src/codebind/py.typed +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: codebind
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.1
|
|
4
4
|
Summary: A frontend-neutral model loop for persistent IPython sessions.
|
|
5
5
|
Keywords: ai,ipython,llm,repl,agents
|
|
6
6
|
Author: Giovanni Gravili
|
|
@@ -8,6 +8,7 @@ Author-email: Giovanni Gravili <ghovax@users.noreply.github.com>
|
|
|
8
8
|
License-Expression: MIT
|
|
9
9
|
License-File: LICENSE
|
|
10
10
|
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Framework :: Jupyter :: JupyterLab :: Extensions :: Prebuilt
|
|
11
12
|
Classifier: Intended Audience :: Developers
|
|
12
13
|
Classifier: Operating System :: OS Independent
|
|
13
14
|
Classifier: Programming Language :: Python :: 3
|
|
@@ -61,7 +62,13 @@ Codebind does not load files or construct a project prompt automatically. The us
|
|
|
61
62
|
|
|
62
63
|
## Jupyter
|
|
63
64
|
|
|
64
|
-
|
|
65
|
+
Start JupyterLab with Codebind from any directory without a permanent installation:
|
|
66
|
+
|
|
67
|
+
```console
|
|
68
|
+
uvx --from jupyterlab --with codebind jupyter lab
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Or install both packages into the same environment, then start JupyterLab normally:
|
|
65
72
|
|
|
66
73
|
```console
|
|
67
74
|
pip install codebind jupyterlab
|
|
@@ -72,15 +79,19 @@ Load Codebind in a notebook:
|
|
|
72
79
|
|
|
73
80
|
```python
|
|
74
81
|
%load_ext codebind
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Run that cell once so JupyterLab can connect to the extension, then use Codebind in later cells:
|
|
75
85
|
|
|
86
|
+
```python
|
|
76
87
|
models = Models({"openai": "OPENAI_API_KEY"})
|
|
77
88
|
model = models.chat("openai/gpt-5")
|
|
78
89
|
await chat.asend("Inspect the current notebook state.", model)
|
|
79
90
|
```
|
|
80
91
|
|
|
81
|
-
Codebind
|
|
92
|
+
The Codebind package includes a prebuilt JupyterLab extension. In JupyterLab, each model-authored IPython execution becomes a genuine code cell with its native execution count and outputs, and the assistant response becomes a rendered Markdown cell. The cells are ordinary notebook content and are saved with the notebook.
|
|
82
93
|
|
|
83
|
-
|
|
94
|
+
Other IPython frontends use the standard MIME display protocol instead. They still receive syntax-highlighted code, assistant Markdown, stdout, tracebacks, rich results, and native IPython history without Codebind depending on their UI.
|
|
84
95
|
|
|
85
96
|
## ChatGPT account login
|
|
86
97
|
|
|
@@ -37,7 +37,13 @@ Codebind does not load files or construct a project prompt automatically. The us
|
|
|
37
37
|
|
|
38
38
|
## Jupyter
|
|
39
39
|
|
|
40
|
-
|
|
40
|
+
Start JupyterLab with Codebind from any directory without a permanent installation:
|
|
41
|
+
|
|
42
|
+
```console
|
|
43
|
+
uvx --from jupyterlab --with codebind jupyter lab
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Or install both packages into the same environment, then start JupyterLab normally:
|
|
41
47
|
|
|
42
48
|
```console
|
|
43
49
|
pip install codebind jupyterlab
|
|
@@ -48,15 +54,19 @@ Load Codebind in a notebook:
|
|
|
48
54
|
|
|
49
55
|
```python
|
|
50
56
|
%load_ext codebind
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Run that cell once so JupyterLab can connect to the extension, then use Codebind in later cells:
|
|
51
60
|
|
|
61
|
+
```python
|
|
52
62
|
models = Models({"openai": "OPENAI_API_KEY"})
|
|
53
63
|
model = models.chat("openai/gpt-5")
|
|
54
64
|
await chat.asend("Inspect the current notebook state.", model)
|
|
55
65
|
```
|
|
56
66
|
|
|
57
|
-
Codebind
|
|
67
|
+
The Codebind package includes a prebuilt JupyterLab extension. In JupyterLab, each model-authored IPython execution becomes a genuine code cell with its native execution count and outputs, and the assistant response becomes a rendered Markdown cell. The cells are ordinary notebook content and are saved with the notebook.
|
|
58
68
|
|
|
59
|
-
|
|
69
|
+
Other IPython frontends use the standard MIME display protocol instead. They still receive syntax-highlighted code, assistant Markdown, stdout, tracebacks, rich results, and native IPython history without Codebind depending on their UI.
|
|
60
70
|
|
|
61
71
|
## ChatGPT account login
|
|
62
72
|
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "codebind-jupyterlab",
|
|
3
|
+
"version": "0.4.1",
|
|
4
|
+
"description": "Native JupyterLab cells for Codebind model executions.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"main": "lib/index.js",
|
|
7
|
+
"types": "lib/index.d.ts",
|
|
8
|
+
"files": [
|
|
9
|
+
"lib/**/*"
|
|
10
|
+
],
|
|
11
|
+
"scripts": {
|
|
12
|
+
"build": "jlpm run clean && jlpm run build:lib && jupyter-builder build && jlpm run build:install",
|
|
13
|
+
"build:install": "node -e \"require('node:fs').copyFileSync('install.json', '../data/share/jupyter/labextensions/codebind-jupyterlab/install.json')\"",
|
|
14
|
+
"build:lib": "tsc",
|
|
15
|
+
"clean": "rimraf lib tsconfig.tsbuildinfo"
|
|
16
|
+
},
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"@jupyterlab/application": "^4.0.0",
|
|
19
|
+
"@jupyterlab/cells": "^4.0.0",
|
|
20
|
+
"@jupyterlab/nbformat": "^4.0.0",
|
|
21
|
+
"@jupyterlab/notebook": "^4.0.0",
|
|
22
|
+
"@jupyterlab/services": "^7.0.0"
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"@jupyter/builder": "^1.2.0",
|
|
26
|
+
"rimraf": "^6.0.0",
|
|
27
|
+
"typescript": "~5.7.0"
|
|
28
|
+
},
|
|
29
|
+
"jupyterlab": {
|
|
30
|
+
"extension": true,
|
|
31
|
+
"outputDir": "../data/share/jupyter/labextensions/codebind-jupyterlab",
|
|
32
|
+
"_build": {
|
|
33
|
+
"load": "static/remoteEntry.6f017385dfc989f1.js",
|
|
34
|
+
"extension": "./extension"
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
codebind-0.4.1/data/share/jupyter/labextensions/codebind-jupyterlab/static/590.6544266cd73a003b.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";(self.rspackChunkcodebind_jupyterlab=self.rspackChunkcodebind_jupyterlab||[]).push([[590],{509(e,t,n){n.r(t);var o=n(171);function l(e){let t=e.sessionContext.session?.kernel;if(!t)return;let n=null,l=new Map;t.registerCommTarget("codebind",(u,c)=>{u.onMsg=u=>{var c;let d,i,r=u.content.data;if(!("object"==typeof r&&null!==r&&("markdown_cell"===r.type?"string"==typeof r.source:"code_cell_started"===r.type?"string"==typeof r.cell_id&&"string"==typeof r.source:"code_cell_output"===r.type?"string"==typeof r.cell_id&&"object"==typeof r.output&&null!==r.output:"code_cell_clear"===r.type?"string"==typeof r.cell_id&&"boolean"==typeof r.wait:"code_cell_finished"===r.type&&"string"==typeof r.cell_id&&("number"==typeof r.execution_count||null===r.execution_count)&&Array.isArray(r.outputs))))return;if("code_cell_output"===r.type)return void l.get(r.cell_id)?.outputs.add(r.output);if("code_cell_clear"===r.type)return void l.get(r.cell_id)?.outputs.clear(r.wait);if("code_cell_finished"===r.type){let e=l.get(r.cell_id);if(!e)return;e.outputs.fromJSON(r.outputs),e.executionCount=r.execution_count,e.executionState="idle",n&&null===n.parentExecutionCount&&null!==r.execution_count&&(n.parentExecutionCount=r.execution_count-1);return}let s=(()=>{if(n)return n;let o=e.content,l=o.widgets.findIndex(e=>"code"===e.model.type&&"running"===e.model.executionState);n={parentModel:l>=0?o.widgets[l].model:null,parentExecutionCount:null,resumeModel:o.activeCell?.model??null,nextIndex:l>=0?l+1:o.activeCell?o.activeCellIndex+1:0};let u=(o,l)=>{"idle"===l&&(t.statusChanged.disconnect(u),(()=>{if(!n)return;let t=e.content,o=n;if(n=null,o.parentModel&&null!==o.parentExecutionCount&&(o.parentModel.executionCount=o.parentExecutionCount),o.resumeModel){let e=t.widgets.findIndex(e=>e.model===o.resumeModel);e>=0&&(t.activeCellIndex=e)}})())};return t.statusChanged.connect(u),n})(),a=(c=s.nextIndex,(i=(d=e.content).model)?("code_cell_started"===r.type?i.sharedModel.insertCell(c,{cell_type:"code",source:r.source,metadata:{trusted:!0},execution_count:null,outputs:[]}):i.sharedModel.insertCell(c,{cell_type:"markdown",source:r.source,metadata:{}}),d.activeCellIndex=c,d.deselectAll(),"markdown_cell"===r.type&&o.NotebookActions.run(d),d.scrollToItem(c),d.widgets[c]?.model??null):null);"code_cell_started"===r.type&&a?.type==="code"&&(a.executionState="running",l.set(r.cell_id,a)),s.nextIndex+=1},u.send({type:"ready"})})}function u(e){e.sessionContext.ready.then(()=>l(e)),e.sessionContext.kernelChanged.connect(()=>l(e))}let c={id:"codebind-jupyterlab:plugin",description:"Insert Codebind executions as native notebook cells.",autoStart:!0,requires:[o.INotebookTracker],activate:(e,t)=>{t.forEach(u),t.widgetAdded.connect((e,t)=>u(t))}};n.d(t,{},{default:c})}}]);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var _JUPYTERLAB;(()=>{"use strict";var e,n,r,t,o,i,u,a,c,l,f,s,p,d,h,v,g,m,y,b,S,j,k,w,E,x,T,P,M,A,C,O,D,_,L,N,$,q={457(e,n,r){var t={"./index":()=>r.e(590).then(()=>()=>r(509)),"./extension":()=>r.e(590).then(()=>()=>r(509))},o=function(e,n){return r.R=n,n=r.o(t,e)?t[e]():Promise.resolve().then(()=>{throw Error('Module "'+e+'" does not exist in container.')}),r.R=void 0,n},i=function(e,n){if(r.S){var t="default",o=r.S[t];if(o&&o!==e)throw Error("Container initialization failed as it has already been initialized with a different share scope");return r.S[t]=e,r.I(t,n)}};r.d(n,{get:()=>o,init:()=>i})}},z={};function I(e){var n=z[e];if(void 0!==n)return n.exports;var r=z[e]={exports:{}};return q[e](r,r.exports,I),r.exports}I.m=q,I.c=z,I.n=e=>{var n=e&&e.__esModule?()=>e.default:()=>e;return I.d(n,{a:n}),n},I.d=(e,n,r)=>{var t=(n,r)=>{for(var t in n)I.o(n,t)&&!I.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,[r]:n[t]})};t(n,"get"),t(r,"value")},I.f={},I.e=e=>Promise.all(Object.keys(I.f).reduce((n,r)=>(I.f[r](e,n),n),[])),I.u=e=>""+e+".6544266cd73a003b.js?v=6544266cd73a003b",I.g=(()=>{if("object"==typeof globalThis)return globalThis;try{return this||Function("return this")()}catch(e){if("object"==typeof window)return window}})(),I.o=(e,n)=>Object.prototype.hasOwnProperty.call(e,n),R={},I.l=function(e,n,r,t){if(R[e])return void R[e].push(n);if(void 0!==r)for(var o,i,u=document.getElementsByTagName("script"),a=0;a<u.length;a++){var c=u[a];if(c.getAttribute("src")==e||c.getAttribute("data-rspack")=="codebind-jupyterlab:"+r){o=c;break}}o||(i=!0,(o=document.createElement("script")).timeout=120,I.nc&&o.setAttribute("nonce",I.nc),o.setAttribute("data-rspack","codebind-jupyterlab:"+r),o.src=e),R[e]=[n];var l=function(n,r){o.onerror=o.onload=null,clearTimeout(f);var t=R[e];if(delete R[e],o.parentNode&&o.parentNode.removeChild(o),t&&t.forEach(function(e){return e(r)}),n)return n(r)},f=setTimeout(l.bind(null,void 0,{type:"timeout",target:o}),12e4);o.onerror=l.bind(null,o.onerror),o.onload=l.bind(null,o.onload),i&&document.head.appendChild(o)},I.r=e=>{"u">typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},I.S={},I.initializeSharingData={scopeToSharingDataMapping:{default:[{name:"codebind-jupyterlab",version:"0.4.1",factory:()=>I.e(590).then(()=>()=>I(509)),eager:0,treeShakingMode:null}]},uniqueName:"codebind-jupyterlab"},U={},B={},I.I=function(e,n){n||(n=[]);var r=B[e];if(r||(r=B[e]={}),!(n.indexOf(r)>=0)){if(n.push(r),U[e])return U[e];I.o(I.S,e)||(I.S[e]={});var t=I.S[e],o=function(e){"u">typeof console&&console.warn&&console.warn(e)},i=I.initializeSharingData.uniqueName,u=function(e,n,r,o){var u=t[e]=t[e]||{},a=u[n];(!a||!a.loaded&&(!o!=!a.eager?o:i>a.from))&&(u[n]={get:r,from:i,eager:!!o})},a=function(r){var t=function(e){o("Initialization of sharing external failed: "+e)};try{var i=I(r);if(!i)return;var u=function(r){return r&&r.init&&r.init(I.S[e],n)};if(i.then)return c.push(i.then(u,t));var a=u(i);if(a&&a.then)return c.push(a.catch(t))}catch(e){t(e)}},c=[],l=I.initializeSharingData.scopeToSharingDataMapping;return(l[e]&&l[e].forEach(function(e){"object"==typeof e?u(e.name,e.version,e.factory,e.eager):a(e)}),c.length)?U[e]=Promise.all(c).then(function(){return U[e]=1}):U[e]=1}},I.g.importScripts&&(V=I.g.location+"");var R,U,B,V,J=I.g.document;if(!V&&J&&(J.currentScript&&"SCRIPT"===J.currentScript.tagName.toUpperCase()&&(V=J.currentScript.src),!V)){var Y=J.getElementsByTagName("script");if(Y.length)for(var K=Y.length-1;K>-1&&(!V||!/^http(s?):/.test(V));)V=Y[K--].src}if(!V)throw Error("Automatic publicPath is not supported in this browser");I.p=V=V.replace(/^blob:/,"").replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),I.consumesLoadingData={chunkMapping:{590:["171"]},moduleIdToConsumeDataMapping:{171:{shareScope:"default",shareKey:"@jupyterlab/notebook",import:null,requiredVersion:"^4.6.3",strictVersion:!1,singleton:!0,eager:!1,fallback:void 0,treeShakingMode:null}},initialConsumes:[]},e=function(e){return e.split(".").map(function(e){return+e==e?+e:e})},n=function(n){var r=function(n){var r=/^([^-+]+)?(?:-([^+]+))?(?:\+(.+))?$/.exec(n),t=r[1]?[0].concat(e(r[1])):[0];r[2]&&(t.length++,t.push.apply(t,e(r[2])));let o=t[t.length-1];for(;t.length&&(void 0===o||/^[*xX]$/.test(o));)t.pop(),o=t[t.length-1];return t},t=function(e){return 1===e.length?[0]:2===e.length?[1].concat(e.slice(1)):3===e.length?[2].concat(e.slice(1)):[e.length].concat(e.slice(1))},o=function(e){return[-e[0]-1].concat(e.slice(1))},i=function(e){let n=/^(\^|~|<=|<|>=|>|=|v|!)/.exec(e),i=n?n[0]:"",u=r(i.length?e.slice(i.length).trim():e.trim());switch(i){case"^":if(u.length>1&&0===u[1]){if(u.length>2&&0===u[2])return[3].concat(u.slice(1));return[2].concat(u.slice(1))}return[1].concat(u.slice(1));case"~":return[2].concat(u.slice(1));case">=":return u;case"=":case"v":case"":return t(u);case"<":return o(u);case">":return[,t(u),0,u,2];case"<=":return[,t(u),o(u),1];case"!":return[,t(u),0];default:throw Error("Unexpected start value")}},u=function(e,n){if(1===e.length)return e[0];let r=[];for(let n of e.slice().reverse())0 in n?r.push(n):r.push.apply(r,n.slice(1));return[,].concat(r,e.slice(1).map(()=>n))};return u(n.split(/\s*\|\|\s*/).map(function(e){let n=e.split(/\s+-\s+/);if(1===n.length){e=e.trim();let n=[],r=/[-0-9A-Za-z]\s+/g;for(var a,c=0;a=r.exec(e);){let r=a.index+1;n.push(i(e.slice(c,r).trim())),c=r}return n.push(i(e.slice(c).trim())),u(n,2)}let l=r(n[0]),f=r(n[1]);return[,t(f),o(f),1,l,2]}),1)},r=function(n){var r=/^([^-+]+)?(?:-([^+]+))?(?:\+(.+))?$/.exec(n),t=r[1]?e(r[1]):[];return r[2]&&(t.length++,t.push.apply(t,e(r[2]))),r[3]&&(t.push([]),t.push.apply(t,e(r[3]))),t},t=function(e,n){e=r(e),n=r(n);for(var t=0;;){if(t>=e.length)return t<n.length&&"u"!=(typeof n[t])[0];var o=e[t],i=(typeof o)[0];if(t>=n.length)return"u"==i;var u=n[t],a=(typeof u)[0];if(i==a){if("o"!=i&&"u"!=i&&o!=u)return o<u;t++}else{if("o"==i&&"n"==a)return!0;return"s"==a||"u"==i}}},o=function(e){var n=e[0],r="";if(1===e.length)return"*";if(n+.5){r+=0==n?">=":-1==n?"<":1==n?"^":2==n?"~":n>0?"=":"!=";for(var t=1,i=1;i<e.length;i++){var u=e[i],a=(typeof u)[0];t--,r+="u"==a?"-":(t>0?".":"")+(t=2,u)}return r}for(var c=[],i=1;i<e.length;i++){var u=e[i];c.push(0===u?"not("+l()+")":1===u?"("+l()+" || "+l()+")":2===u?c.pop()+" "+c.pop():o(u))}return l();function l(){return c.pop().replace(/^\((.+)\)$/,"$1")}},i=function(e,n){if(0 in e){n=r(n);var t=e[0],o=t<0;o&&(t=-t-1);for(var u=0,a=1,c=!0;;a++,u++){var l,f,s=a<e.length?(typeof e[a])[0]:"";if(u>=n.length||"o"==(f=(typeof(l=n[u]))[0])){if(!c)return!0;if("u"==s)return a>t&&!o;return""==s!=o}if("u"==f){if(!c||"u"!=s)return!1}else if(c)if(s==f)if(a<=t){if(l!=e[a])return!1}else{if(o?l>e[a]:l<e[a])return!1;l!=e[a]&&(c=!1)}else if("s"!=s&&"n"!=s){if(o||a<=t)return!1;c=!1,a--}else{if(a<=t||f<s!=o)return!1;c=!1}else"s"!=s&&"n"!=s&&(c=!1,a--)}}for(var p=[],d=p.pop.bind(p),u=1;u<e.length;u++){var h=e[u];p.push(1==h?d()|d():2==h?d()&d():h?i(h,n):!d())}return!!d()},u=function(e,n){var r=I.S[e];if(!r||!I.o(r,n))throw Error("Shared module "+n+" doesn't exist in shared scope "+e);return r},a=function(e,n){var r=e[n],n=Object.keys(r).reduce(function(e,n){return!e||t(e,n)?n:e},0);return n&&r[n]},c=function(e,n){var r=e[n];return Object.keys(r).reduce(function(e,n){return!e||!r[e].loaded&&t(e,n)?n:e},0)},l=function(e,n,r,t){return"Unsatisfied version "+r+" from "+(r&&e[n][r].from)+" of shared singleton module "+n+" (required "+o(t)+")"},f=function(e,n,r,t){var o=c(e,r);return y(e[r][o])},s=function(e,n,r,t){var o=c(e,r);return i(t,o)||g(l(e,r,o,t)),y(e[r][o])},p=function(e,n,r,t){var o=c(e,r);if(!i(t,o))throw Error(l(e,r,o,t));return y(e[r][o])},d=function(e,n,r){var o=e[n],n=Object.keys(o).reduce(function(e,n){return i(r,n)&&(!e||t(e,n))?n:e},0);return n&&o[n]},h=function(e,n,r,t){var i=e[r];return"No satisfying version ("+o(t)+") of shared module "+r+" found in shared scope "+n+".\nAvailable versions: "+Object.keys(i).map(function(e){return e+" from "+i[e].from}).join(", ")},v=function(e,n,r,t){var o=d(e,r,t);if(o)return y(o);throw Error(h(e,n,r,t))},g=function(e){"u">typeof console&&console.warn&&console.warn(e)},m=function(e,n,r,t){g(h(e,n,r,t))},y=function(e){return e.loaded=1,e.get()},S=(b=function(e){return function(n,r,t,o){var i=I.I(n);return i&&i.then?i.then(e.bind(e,n,I.S[n],r,t,o)):e(n,I.S[n],r,t,o)}})(function(e,n,r){return u(e,r),y(a(n,r))}),j=b(function(e,n,r,t){return n&&I.o(n,r)?y(a(n,r)):t()}),k=b(function(e,n,r,t){return u(e,r),y(d(n,r,t)||m(n,e,r,t)||a(n,r))}),w=b(function(e,n,r){return u(e,r),f(n,e,r)}),E=b(function(e,n,r,t){return u(e,r),s(n,e,r,t)}),x=b(function(e,n,r,t){return u(e,r),v(n,e,r,t)}),T=b(function(e,n,r,t){return u(e,r),p(n,e,r,t)}),P=b(function(e,n,r,t,o){return n&&I.o(n,r)?y(d(n,r,t)||m(n,e,r,t)||a(n,r)):o()}),M=b(function(e,n,r,t){return n&&I.o(n,r)?f(n,e,r):t()}),A=b(function(e,n,r,t,o){return n&&I.o(n,r)?s(n,e,r,t):o()}),C=b(function(e,n,r,t,o){var i=n&&I.o(n,r)&&d(n,r,t);return i?y(i):o()}),O=b(function(e,n,r,t,o){return n&&I.o(n,r)?p(n,e,r,t):o()}),D=function(e){var r=!1,t=!1,o=!1,i=!1,u=[e.shareScope,e.shareKey];return(e.requiredVersion?(e.strictVersion&&(r=!0),e.singleton&&(t=!0),u.push(n(e.requiredVersion)),o=!0):e.singleton&&(t=!0),e.fallback&&(i=!0,u.push(e.fallback)),r&&t&&o&&i)?function(){return O.apply(null,u)}:r&&o&&i?function(){return C.apply(null,u)}:t&&o&&i?function(){return A.apply(null,u)}:r&&t&&o?function(){return T.apply(null,u)}:t&&i?function(){return M.apply(null,u)}:o&&i?function(){return P.apply(null,u)}:r&&o?function(){return x.apply(null,u)}:t&&o?function(){return E.apply(null,u)}:t?function(){return w.apply(null,u)}:o?function(){return k.apply(null,u)}:i?function(){return j.apply(null,u)}:function(){return S.apply(null,u)}},_={},I.f.consumes=function(e,n){var r=I.consumesLoadingData.moduleIdToConsumeDataMapping,t=I.consumesLoadingData.chunkMapping;I.o(t,e)&&t[e].forEach(function(e){if(I.o(_,e))return n.push(_[e]);var t=function(n){_[e]=0,I.m[e]=function(r){delete I.c[e],r.exports=n()}},o=function(n){delete _[e],I.m[e]=function(r){throw delete I.c[e],n}};try{var i=D(r[e])();i.then?n.push(_[e]=i.then(t).catch(o)):t(i)}catch(e){o(e)}})},L={871:0},I.f.j=function(e,n){var r=I.o(L,e)?L[e]:void 0;if(0!==r)if(r)n.push(r[2]);else{var t=new Promise((n,t)=>r=L[e]=[n,t]);n.push(r[2]=t);var o=I.p+I.u(e),i=Error();I.l(o,function(n){if(I.o(L,e)&&(0!==(r=L[e])&&(L[e]=void 0),r)){var t=n&&("load"===n.type?"missing":n.type),o=n&&n.target&&n.target.src;i.message="Loading chunk "+e+" failed.\n("+t+": "+o+")",i.name="ChunkLoadError",i.type=t,i.request=o,r[1](i)}},"chunk-"+e,e)}},N=(e,n)=>{var r,t,[o,i,u]=n,a=0;if(o.some(e=>0!==L[e])){for(r in i)I.o(i,r)&&(I.m[r]=i[r]);u&&u(I)}for(e&&e(n);a<o.length;a++)t=o[a],I.o(L,t)&&L[t]&&L[t][0](),L[t]=0},($=self.rspackChunkcodebind_jupyterlab=self.rspackChunkcodebind_jupyterlab||[]).forEach(N.bind(null,0)),$.push=N.bind(null,$.push.bind($));var F=I(457);(_JUPYTERLAB=void 0===_JUPYTERLAB?{}:_JUPYTERLAB)["codebind-jupyterlab"]=F})();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
nodeLinker: node-modules
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "codebind-jupyterlab",
|
|
3
|
+
"version": "0.4.1",
|
|
4
|
+
"description": "Native JupyterLab cells for Codebind model executions.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"main": "lib/index.js",
|
|
7
|
+
"types": "lib/index.d.ts",
|
|
8
|
+
"files": [
|
|
9
|
+
"lib/**/*"
|
|
10
|
+
],
|
|
11
|
+
"scripts": {
|
|
12
|
+
"build": "jlpm run clean && jlpm run build:lib && jupyter-builder build && jlpm run build:install",
|
|
13
|
+
"build:install": "node -e \"require('node:fs').copyFileSync('install.json', '../data/share/jupyter/labextensions/codebind-jupyterlab/install.json')\"",
|
|
14
|
+
"build:lib": "tsc",
|
|
15
|
+
"clean": "rimraf lib tsconfig.tsbuildinfo"
|
|
16
|
+
},
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"@jupyterlab/application": "^4.0.0",
|
|
19
|
+
"@jupyterlab/cells": "^4.0.0",
|
|
20
|
+
"@jupyterlab/nbformat": "^4.0.0",
|
|
21
|
+
"@jupyterlab/notebook": "^4.0.0",
|
|
22
|
+
"@jupyterlab/services": "^7.0.0"
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"@jupyter/builder": "^1.2.0",
|
|
26
|
+
"rimraf": "^6.0.0",
|
|
27
|
+
"typescript": "~5.7.0"
|
|
28
|
+
},
|
|
29
|
+
"jupyterlab": {
|
|
30
|
+
"extension": true,
|
|
31
|
+
"outputDir": "../data/share/jupyter/labextensions/codebind-jupyterlab"
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
import {
|
|
2
|
+
JupyterFrontEnd,
|
|
3
|
+
JupyterFrontEndPlugin
|
|
4
|
+
} from '@jupyterlab/application';
|
|
5
|
+
import { ICellModel, ICodeCellModel } from '@jupyterlab/cells';
|
|
6
|
+
import * as nbformat from '@jupyterlab/nbformat';
|
|
7
|
+
import {
|
|
8
|
+
INotebookTracker,
|
|
9
|
+
NotebookActions,
|
|
10
|
+
NotebookPanel
|
|
11
|
+
} from '@jupyterlab/notebook';
|
|
12
|
+
import { Kernel, KernelMessage } from '@jupyterlab/services';
|
|
13
|
+
|
|
14
|
+
const TARGET_NAME = 'codebind';
|
|
15
|
+
|
|
16
|
+
interface CodeCellStartedMessage {
|
|
17
|
+
type: 'code_cell_started';
|
|
18
|
+
cell_id: string;
|
|
19
|
+
source: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
interface CodeCellFinishedMessage {
|
|
23
|
+
type: 'code_cell_finished';
|
|
24
|
+
cell_id: string;
|
|
25
|
+
execution_count: number | null;
|
|
26
|
+
outputs: nbformat.IOutput[];
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
interface CodeCellOutputMessage {
|
|
30
|
+
type: 'code_cell_output';
|
|
31
|
+
cell_id: string;
|
|
32
|
+
output: nbformat.IOutput;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
interface CodeCellClearMessage {
|
|
36
|
+
type: 'code_cell_clear';
|
|
37
|
+
cell_id: string;
|
|
38
|
+
wait: boolean;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
interface MarkdownCellMessage {
|
|
42
|
+
type: 'markdown_cell';
|
|
43
|
+
source: string;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
type CodebindMessage =
|
|
47
|
+
| CodeCellStartedMessage
|
|
48
|
+
| CodeCellFinishedMessage
|
|
49
|
+
| CodeCellOutputMessage
|
|
50
|
+
| CodeCellClearMessage
|
|
51
|
+
| MarkdownCellMessage;
|
|
52
|
+
type InsertMessage = CodeCellStartedMessage | MarkdownCellMessage;
|
|
53
|
+
|
|
54
|
+
interface TurnState {
|
|
55
|
+
parentModel: ICodeCellModel | null;
|
|
56
|
+
parentExecutionCount: number | null;
|
|
57
|
+
resumeModel: ICellModel | null;
|
|
58
|
+
nextIndex: number;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function isCodebindMessage(value: unknown): value is CodebindMessage {
|
|
62
|
+
if (typeof value !== 'object' || value === null) {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
const message = value as Record<string, unknown>;
|
|
66
|
+
if (message.type === 'markdown_cell') {
|
|
67
|
+
return typeof message.source === 'string';
|
|
68
|
+
}
|
|
69
|
+
if (message.type === 'code_cell_started') {
|
|
70
|
+
return (
|
|
71
|
+
typeof message.cell_id === 'string' &&
|
|
72
|
+
typeof message.source === 'string'
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
if (message.type === 'code_cell_output') {
|
|
76
|
+
return (
|
|
77
|
+
typeof message.cell_id === 'string' &&
|
|
78
|
+
typeof message.output === 'object' &&
|
|
79
|
+
message.output !== null
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
if (message.type === 'code_cell_clear') {
|
|
83
|
+
return typeof message.cell_id === 'string' && typeof message.wait === 'boolean';
|
|
84
|
+
}
|
|
85
|
+
return (
|
|
86
|
+
message.type === 'code_cell_finished' &&
|
|
87
|
+
typeof message.cell_id === 'string' &&
|
|
88
|
+
(typeof message.execution_count === 'number' ||
|
|
89
|
+
message.execution_count === null) &&
|
|
90
|
+
Array.isArray(message.outputs)
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function insertCell(
|
|
95
|
+
panel: NotebookPanel,
|
|
96
|
+
message: InsertMessage,
|
|
97
|
+
index: number
|
|
98
|
+
): ICellModel | null {
|
|
99
|
+
const notebook = panel.content;
|
|
100
|
+
const model = notebook.model;
|
|
101
|
+
if (!model) {
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (message.type === 'code_cell_started') {
|
|
106
|
+
model.sharedModel.insertCell(index, {
|
|
107
|
+
cell_type: 'code',
|
|
108
|
+
source: message.source,
|
|
109
|
+
metadata: { trusted: true },
|
|
110
|
+
execution_count: null,
|
|
111
|
+
outputs: []
|
|
112
|
+
});
|
|
113
|
+
} else {
|
|
114
|
+
model.sharedModel.insertCell(index, {
|
|
115
|
+
cell_type: 'markdown',
|
|
116
|
+
source: message.source,
|
|
117
|
+
metadata: {}
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
notebook.activeCellIndex = index;
|
|
122
|
+
notebook.deselectAll();
|
|
123
|
+
if (message.type === 'markdown_cell') {
|
|
124
|
+
void NotebookActions.run(notebook);
|
|
125
|
+
}
|
|
126
|
+
void notebook.scrollToItem(index);
|
|
127
|
+
return notebook.widgets[index]?.model ?? null;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function registerKernel(panel: NotebookPanel): void {
|
|
131
|
+
const kernel = panel.sessionContext.session?.kernel;
|
|
132
|
+
if (!kernel) {
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
let turn: TurnState | null = null;
|
|
137
|
+
const codeCells = new Map<string, ICodeCellModel>();
|
|
138
|
+
|
|
139
|
+
const finishTurn = (): void => {
|
|
140
|
+
if (!turn) {
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
const notebook = panel.content;
|
|
144
|
+
const completed = turn;
|
|
145
|
+
turn = null;
|
|
146
|
+
if (
|
|
147
|
+
completed.parentModel &&
|
|
148
|
+
completed.parentExecutionCount !== null
|
|
149
|
+
) {
|
|
150
|
+
completed.parentModel.executionCount = completed.parentExecutionCount;
|
|
151
|
+
}
|
|
152
|
+
if (completed.resumeModel) {
|
|
153
|
+
const index = notebook.widgets.findIndex(
|
|
154
|
+
widget => widget.model === completed.resumeModel
|
|
155
|
+
);
|
|
156
|
+
if (index >= 0) {
|
|
157
|
+
notebook.activeCellIndex = index;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
const beginTurn = (): TurnState => {
|
|
163
|
+
if (turn) {
|
|
164
|
+
return turn;
|
|
165
|
+
}
|
|
166
|
+
const notebook = panel.content;
|
|
167
|
+
const parentIndex = notebook.widgets.findIndex(
|
|
168
|
+
widget =>
|
|
169
|
+
widget.model.type === 'code' &&
|
|
170
|
+
(widget.model as ICodeCellModel).executionState === 'running'
|
|
171
|
+
);
|
|
172
|
+
const parentModel =
|
|
173
|
+
parentIndex >= 0
|
|
174
|
+
? (notebook.widgets[parentIndex].model as ICodeCellModel)
|
|
175
|
+
: null;
|
|
176
|
+
turn = {
|
|
177
|
+
parentModel,
|
|
178
|
+
parentExecutionCount: null,
|
|
179
|
+
resumeModel: notebook.activeCell?.model ?? null,
|
|
180
|
+
nextIndex:
|
|
181
|
+
parentIndex >= 0
|
|
182
|
+
? parentIndex + 1
|
|
183
|
+
: notebook.activeCell
|
|
184
|
+
? notebook.activeCellIndex + 1
|
|
185
|
+
: 0
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
const onStatus = (
|
|
189
|
+
_sender: Kernel.IKernelConnection,
|
|
190
|
+
status: Kernel.Status
|
|
191
|
+
): void => {
|
|
192
|
+
if (status === 'idle') {
|
|
193
|
+
kernel.statusChanged.disconnect(onStatus);
|
|
194
|
+
finishTurn();
|
|
195
|
+
}
|
|
196
|
+
};
|
|
197
|
+
kernel.statusChanged.connect(onStatus);
|
|
198
|
+
return turn;
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
kernel.registerCommTarget(
|
|
202
|
+
TARGET_NAME,
|
|
203
|
+
(comm: Kernel.IComm, _message: KernelMessage.ICommOpenMsg) => {
|
|
204
|
+
comm.onMsg = (message: KernelMessage.ICommMsgMsg) => {
|
|
205
|
+
const data = message.content.data;
|
|
206
|
+
if (!isCodebindMessage(data)) {
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
if (data.type === 'code_cell_output') {
|
|
210
|
+
codeCells.get(data.cell_id)?.outputs.add(data.output);
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
if (data.type === 'code_cell_clear') {
|
|
214
|
+
codeCells.get(data.cell_id)?.outputs.clear(data.wait);
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
if (data.type === 'code_cell_finished') {
|
|
218
|
+
const model = codeCells.get(data.cell_id);
|
|
219
|
+
if (!model) {
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
model.outputs.fromJSON(data.outputs);
|
|
223
|
+
model.executionCount = data.execution_count;
|
|
224
|
+
model.executionState = 'idle';
|
|
225
|
+
if (
|
|
226
|
+
turn &&
|
|
227
|
+
turn.parentExecutionCount === null &&
|
|
228
|
+
data.execution_count !== null
|
|
229
|
+
) {
|
|
230
|
+
turn.parentExecutionCount = data.execution_count - 1;
|
|
231
|
+
}
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
const activeTurn = beginTurn();
|
|
236
|
+
const model = insertCell(panel, data, activeTurn.nextIndex);
|
|
237
|
+
if (data.type === 'code_cell_started' && model?.type === 'code') {
|
|
238
|
+
const code = model as ICodeCellModel;
|
|
239
|
+
code.executionState = 'running';
|
|
240
|
+
codeCells.set(data.cell_id, code);
|
|
241
|
+
}
|
|
242
|
+
activeTurn.nextIndex += 1;
|
|
243
|
+
};
|
|
244
|
+
comm.send({ type: 'ready' });
|
|
245
|
+
}
|
|
246
|
+
);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
function connectPanel(panel: NotebookPanel): void {
|
|
250
|
+
void panel.sessionContext.ready.then(() => registerKernel(panel));
|
|
251
|
+
panel.sessionContext.kernelChanged.connect(() => registerKernel(panel));
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
const plugin: JupyterFrontEndPlugin<void> = {
|
|
255
|
+
id: 'codebind-jupyterlab:plugin',
|
|
256
|
+
description: 'Insert Codebind executions as native notebook cells.',
|
|
257
|
+
autoStart: true,
|
|
258
|
+
requires: [INotebookTracker],
|
|
259
|
+
activate: (_app: JupyterFrontEnd, tracker: INotebookTracker): void => {
|
|
260
|
+
tracker.forEach(connectPanel);
|
|
261
|
+
tracker.widgetAdded.connect((_tracker, panel) => connectPanel(panel));
|
|
262
|
+
}
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
export default plugin;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"allowSyntheticDefaultImports": true,
|
|
4
|
+
"composite": true,
|
|
5
|
+
"declaration": true,
|
|
6
|
+
"esModuleInterop": true,
|
|
7
|
+
"incremental": true,
|
|
8
|
+
"module": "ESNext",
|
|
9
|
+
"moduleResolution": "bundler",
|
|
10
|
+
"outDir": "lib",
|
|
11
|
+
"rootDir": "src",
|
|
12
|
+
"skipLibCheck": true,
|
|
13
|
+
"strict": true,
|
|
14
|
+
"target": "ES2022"
|
|
15
|
+
},
|
|
16
|
+
"include": [
|
|
17
|
+
"src/**/*"
|
|
18
|
+
]
|
|
19
|
+
}
|