Skip to content

Commit

Permalink
feat(copilot): scaffold copilot
Browse files Browse the repository at this point in the history
  • Loading branch information
philippfromme committed Jul 6, 2023
1 parent 3d7fb25 commit cac93e1
Show file tree
Hide file tree
Showing 10 changed files with 268 additions and 2 deletions.
1 change: 1 addition & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
OPENAI_API_KEY="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"
4 changes: 4 additions & 0 deletions assets/bpmn-js.css
Original file line number Diff line number Diff line change
Expand Up @@ -142,3 +142,7 @@
height: 20px;
width: 20px;
}

.layer-copilot {
opacity: 0.5;
}
2 changes: 2 additions & 0 deletions lib/Modeler.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import BendpointsModule from 'diagram-js/lib/features/bendpoints';
import ConnectModule from 'diagram-js/lib/features/connect';
import ConnectionPreviewModule from 'diagram-js/lib/features/connection-preview';
import ContextPadModule from './features/context-pad';
import CopilotModule from './features/copilot';
import CopyPasteModule from './features/copy-paste';
import CreateModule from 'diagram-js/lib/features/create';
import DistributeElementsModule from './features/distribute-elements';
Expand Down Expand Up @@ -175,6 +176,7 @@ Modeler.prototype._modelingModules = [
ConnectModule,
ConnectionPreviewModule,
ContextPadModule,
CopilotModule,
CopyPasteModule,
CreateModule,
DistributeElementsModule,
Expand Down
138 changes: 138 additions & 0 deletions lib/features/copilot/Copilot.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
import { clear as svgClear } from 'tiny-svg';

export default class Copilot {
constructor(
canvas,
createPreview,
directEditing,
eventBus,
keyboard,
modeling,
selection) {
this._canvas = canvas;
this._createPreview = createPreview;
this._directEditing = directEditing;
this._modeling = modeling;
this._selection = selection;

eventBus.on('selection.changed', (context) => {
const { newSelection } = context;

this.clearSuggestion();

if (newSelection.length === 1) {
this.makeSuggestion(newSelection[ 0 ]);
}
});

eventBus.on('directEditing.activate', () => {
this.hideSuggestion();
});

eventBus.on('directEditing.deactivate', () => {
this.showSuggestion();
});

keyboard.addListener((context) => {
if (context.keyEvent.key === 'Tab') {
context.keyEvent.preventDefault();

this.acceptSuggestion();
} else if (context.keyEvent.key === 'Escape') {
this.clearSuggestion();
}
});

this._suggestion = null;

this._layer = canvas.getLayer('copilot', 1000);
}

acceptSuggestion() {
console.log('acceptSuggestion');

if (!this._suggestion) {
return;
}

const {
elements,
position,
target
} = this._suggestion;

const createdElements = this._modeling.createElements(elements, position, target, {
position: 'absolute'
});

this.clearSuggestion();

if (createdElements.length === 1) {
this._selection.select(createdElements[ 0 ]);

this._directEditing.activate(createdElements[ 0 ]);
}
}

makeSuggestion(element) {
console.log('makeSuggestion');

const suggestion = this._suggestion = this.createSuggestion(element);

console.log('suggestion', suggestion);

if (!suggestion) {
return;
}

const { elements } = suggestion;

const group = this._createPreview.createPreview(elements);

this._layer.appendChild(group);
}

showSuggestion() {
console.log('showSuggestion');

this._canvas.showLayer('copilot');
}

hideSuggestion() {
console.log('hideSuggestion');

this._canvas.hideLayer('copilot');
}

clearSuggestion() {
console.log('clearSuggestion');

this._suggestion = null;

svgClear(this._layer);
}

createSuggestion(element) {
console.log('createSuggestion');

if (!this._provider) {
return null;
}

return this._provider.createSuggestion(element);
}

setProvider(provider) {
this._provider = provider;
}
}

Copilot.$inject = [
'canvas',
'createPreview',
'directEditing',
'eventBus',
'keyboard',
'modeling',
'selection'
];
43 changes: 43 additions & 0 deletions lib/features/copilot/OpenAIProvider.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { is } from '../../util/ModelUtil';

import { getMid } from 'diagram-js/lib/layout/LayoutUtil';

const apiKey = process.env.OPENAI_API_KEY;

Check failure on line 5 in lib/features/copilot/OpenAIProvider.js

View workflow job for this annotation

GitHub Actions / Build (ubuntu-20.04)

'apiKey' is assigned a value but never used. Allowed unused vars must match /^_/u

Check failure on line 5 in lib/features/copilot/OpenAIProvider.js

View workflow job for this annotation

GitHub Actions / Build (ubuntu-20.04)

'process' is not defined

export default class OpenAIProvider {
constructor(copilot, elementFactory) {
copilot.setProvider(this);

this._elementFactory = elementFactory;
}

createSuggestion(element) {
const suggestion = {
elements: [],
position: null,
target: element.parent
};

const mid = getMid(element);

Check failure on line 21 in lib/features/copilot/OpenAIProvider.js

View workflow job for this annotation

GitHub Actions / Build (ubuntu-20.04)

'mid' is assigned a value but never used. Allowed unused vars must match /^_/u

if (is(element, 'bpmn:Task')) {
return {
...suggestion,
elements: [
this._elementFactory.createShape({
type: 'bpmn:Task',
x: element.x + element.width + 100,
y: element.y
})
]
};
}

return null;
}
}

OpenAIProvider.$inject = [
'copilot',
'elementFactory'
];
15 changes: 15 additions & 0 deletions lib/features/copilot/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import Copilot from './Copilot';
import OpenAIProvider from './OpenAIProvider';

export default {
__depends__: [

// TODO
],
__init__: [
'copilot',
'openaiprovider'
],
copilot: [ 'type', Copilot ],
openaiprovider: [ 'type', OpenAIProvider ]
};
58 changes: 58 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@
"cross-env": "^7.0.3",
"del": "^6.0.0",
"del-cli": "^5.0.0",
"dotenv-webpack": "^8.0.1",
"eslint": "^8.22.0",
"eslint-plugin-bpmn-io": "^1.0.0",
"eslint-plugin-import": "^2.26.0",
Expand Down
6 changes: 5 additions & 1 deletion test/config/karma.unit.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ var absoluteBasePath = path.resolve(path.join(__dirname, basePath));

var suite = coverage ? 'test/coverageBundle.js' : 'test/testBundle.js';

const Dotenv = require('dotenv-webpack');

module.exports = function(karma) {

Expand Down Expand Up @@ -101,7 +102,10 @@ module.exports = function(karma) {
absoluteBasePath
]
},
devtool: 'eval-source-map'
devtool: 'eval-source-map',
plugins: [
new Dotenv()
]
}
};

Expand Down
2 changes: 1 addition & 1 deletion test/spec/ModelerSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ describe('Modeler', function() {

setBpmnJS(modeler);

enableLogging(modeler, singleStart);
// enableLogging(modeler, singleStart);

return modeler.importXML(xml).then(function(result) {
return { error: null, warnings: result.warnings, modeler: modeler };
Expand Down

0 comments on commit cac93e1

Please sign in to comment.