Skip to content

Commit

Permalink
Merge branch 'master' into langgraph_backend
Browse files Browse the repository at this point in the history
  • Loading branch information
kreneskyp committed Feb 24, 2024
2 parents 016ebe4 + 74f63a5 commit a0c1624
Show file tree
Hide file tree
Showing 7 changed files with 141 additions and 53 deletions.
37 changes: 0 additions & 37 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -1,40 +1,3 @@
IX DUAL LICENSE
Copyright (c) 2023 Peter Krenesky
===============

IX is licensed under a dual MIT and commercial license.

The MIT license applies to only non-commercial use including personal, educational, evaluation, and non-profit use.

Commercial entities may use IX under the MIT license for evaluation purposes only. Evaluation periods are limited to
90 days and may not be extended or repeated without explicit consent.

The commercial license applies to any use of IX in or in support of a commercial product or in support of a for-profit
business activity. Business activity is defined as any activity or process that supports a for-profit business,
including but not limited to: use or in support of a commercial product, use or in support of a commercial service, use
in or in support of a business process, or resale of IX software.

Commercial licenses and evaluation extensions may be obtained by contacting kreneskyp@gmail.com. License terms are
negotiable and may be tailored to your specific needs. Small organizations (less than 10 seats) and individuals may be
eligible for a free license.


# IX Commercial License General Terms
--------------------------------------
Copyright (c) 2023 Peter Krenesky

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.



# FOSS / MIT License Terms
--------------------------------------
MIT License

Copyright (c) 2023 Peter Krenesky
Expand Down
43 changes: 39 additions & 4 deletions frontend/components/code_editor/CodeEditor.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,16 @@ export const CodeEditor = ({ value, language, onChange }) => {
const [editor] = useState(() => withHistory(withReact(createEditor())));
const _value = value || "";

const [lineHeights, setLineHeights] = useState([]); // State to store line heights

const updateLineHeight = (index, height) => {
setLineHeights((prevHeights) => {
const newHeights = [...prevHeights];
newHeights[index] = height;
return newHeights;
});
};

const decorate = useDecorate(editor);
const onKeyDown = useOnKeydown(editor);

Expand Down Expand Up @@ -79,6 +89,19 @@ export const CodeEditor = ({ value, language, onChange }) => {
[onChange]
);

const renderElement = React.useCallback(
(props) => (
<ElementWrapper
key={props.element.line}
{...props}
language={language}
heights={lineHeights}
updateLineHeight={updateLineHeight}
/>
),
[updateLineHeight]
);

return (
<Box
h={"100%"}
Expand All @@ -96,11 +119,11 @@ export const CodeEditor = ({ value, language, onChange }) => {
>
<SetNodeToDecorations />
<HStack spacing={0}>
<LineNumbers />
<LineNumbers lineHeights={lineHeights} />
<Box py={2} w={"100%"}>
<Editable
decorate={decorate}
renderElement={(props) => ElementWrapper(props, language)}
renderElement={renderElement}
renderLeaf={renderLeaf}
onKeyDown={onKeyDown}
/>
Expand All @@ -115,9 +138,10 @@ export const CodeEditor = ({ value, language, onChange }) => {
);
};

const ElementWrapper = (props, language) => {
const ElementWrapper = ({ language, heights, updateLineHeight, ...props }) => {
const { attributes, children, element } = props;
const editor = useSlateStatic();
const lineRef = React.useRef(null);

if (element.type === CodeBlockType) {
Transforms.setNodes(
Expand Down Expand Up @@ -145,10 +169,21 @@ const ElementWrapper = (props, language) => {
);
}

// update parent if code line size changes
React.useEffect(() => {
if (
element.type === CodeLineType &&
lineRef.current &&
heights[element.line] !== lineRef.current.offsetHeight
) {
updateLineHeight(element.line, lineRef.current.offsetHeight);
}
}, [element, children]);

if (element.type === CodeLineType) {
return (
<Box {...attributes} style={{ position: "relative" }}>
{children}
<div ref={lineRef}>{children}</div>
</Box>
);
}
Expand Down
7 changes: 4 additions & 3 deletions frontend/components/code_editor/LineNumbers.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { useSlate } from "slate-react";
import { Box } from "@chakra-ui/react";
import { useColorMode } from "@chakra-ui/react";

export const LineNumbers = () => {
export const LineNumbers = ({ lineHeights }) => {
const editor = useSlate();
const element = editor.children[0];
const lines = element.children || [];
Expand All @@ -20,6 +20,7 @@ export const LineNumbers = () => {
bg={bg}
px={1}
py={2}
pt={3}
fontSize="xs"
fontFamily="monospace"
color={color}
Expand All @@ -28,10 +29,10 @@ export const LineNumbers = () => {
<Box
key={index}
w="full"
h="21px"
h={lineHeights[index] ? `${lineHeights[index]}px` : "21px"}
m={0}
display="flex"
alignItems="end"
alignItems="start"
justifyContent="flex-end"
>
{index + 1}
Expand Down
9 changes: 6 additions & 3 deletions ix/runnable/llm.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,12 @@ def bind(self, **kwargs: Any) -> Runnable[Input, Output]:
"""
kwargs = kwargs.copy()

if "function_call" in kwargs:
if isinstance(kwargs["function_call"], str):
kwargs["function_call"] = {"name": kwargs["function_call"]}
function_call = kwargs.pop("function_call", None)
if function_call:
if isinstance(function_call, str):
kwargs["function_call"] = {"name": function_call}
else:
kwargs["function_call"] = function_call

if "functions" in kwargs:
kwargs["functions"] = [to_openai_fn(obj) for obj in kwargs["functions"]]
Expand Down
7 changes: 7 additions & 0 deletions ix/skills/components.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,13 @@
description="Skill to run",
input_type="IX:skill",
),
NodeTypeField(
name="raise_error",
label="Halt on error",
type="boolean",
description="Halt on error by raising exception",
default=False,
),
],
)

Expand Down
68 changes: 62 additions & 6 deletions ix/skills/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@
import json
import os
import subprocess
import sys
import textwrap
import traceback
from typing import Dict, Any, Optional

from langchain_experimental.utilities import PythonREPL
from pydantic import BaseModel


class MissingTypeHintError(Exception):
Expand Down Expand Up @@ -102,24 +105,77 @@ def parse_skill(
return func_name, input_schema, description


class ErrorResponse(BaseModel):
message: str
traceback: str
line: int


def execute_function(function, raise_errors: bool = False):
try:
result = function()
return result
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
line_number = exc_tb.tb_lineno
error_response = ErrorResponse(
message=str(e),
traceback="".join(traceback.format_tb(exc_tb)),
line=line_number,
)
if raise_errors:
raise e
else:
return error_response


def run_code_with_repl(
code: str, function: str, input: Dict[str, Any], timeout: Optional[int] = None
) -> str:
code: str,
function: str,
input: Dict[str, Any],
timeout: Optional[int] = None,
raise_errors: bool = False,
) -> Any:
# HAX: use globals for I/O with the REPL. Hacky way to avoid serialization.
func_output = []
repl = PythonREPL(
_globals={"func_input": input, "func_output": func_output, "json": json}
_globals={
"func_input": input,
"func_output": func_output,
"json": json,
"ErrorResponse": ErrorResponse,
}
)

# Prepare the command to run in the REPL
command = textwrap.dedent(
f"""
import traceback
import sys
{code}
output = {function}(**func_input)
func_output.append(output)
try:
output = {function}(**func_input)
func_output.append(output)
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
error_response = ErrorResponse(
message=str(e),
traceback=''.join(traceback.format_tb(exc_tb)),
line=exc_tb.tb_lineno
)
func_output.append(error_response)
if raise_errors:
raise e
"""
)

# Run the command in the PythonREPL
response = repl.run(command, timeout)
return func_output[0] if func_output else response
output = func_output[0] if func_output else response

if isinstance(output, ErrorResponse) and raise_errors:
raise Exception(output.message)

return output
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@
"config_schema": {
"display_groups": null,
"properties": {
"raise_error": {
"default": false,
"description": "Halt on error by raising exception",
"label": "Halt on error",
"type": "boolean"
},
"skill_id": {
"description": "Skill to run",
"input_type": "IX:skill",
Expand Down Expand Up @@ -35,6 +41,23 @@
"step": null,
"style": null,
"type": "string"
},
{
"choices": null,
"default": false,
"description": "Halt on error by raising exception",
"init_type": "init",
"input_type": null,
"label": "Halt on error",
"max": null,
"min": null,
"name": "raise_error",
"parent": null,
"required": false,
"secret_key": null,
"step": null,
"style": null,
"type": "boolean"
}
],
"name": "Run Skill",
Expand Down

0 comments on commit a0c1624

Please sign in to comment.