Skip to content

Commit 8b7dedd

Browse files
committed
First step for tool use solution
1 parent ad03d47 commit 8b7dedd

File tree

3 files changed

+184
-21
lines changed

3 files changed

+184
-21
lines changed

README.md

+135-18
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# CEDARScript
22

3+
A SQL-like language for efficient code analysis, transformations, and tool use.
4+
Most useful for AI code assistants.
5+
36
[![PyPI version](https://badge.fury.io/py/cedarscript-grammar.svg)](https://pypi.org/project/cedarscript-grammar/)
47
[![Python Versions](https://img.shields.io/pypi/pyversions/cedarscript-grammar.svg)](https://pypi.org/project/cedarscript-grammar/)
58
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
@@ -13,20 +16,26 @@
1316
- [Key Features](#key-features)
1417
- [Supported Languages](#supported-languages)
1518
- [How can CEDARScript be used](#how-can-cedarscript-be-used)
16-
- [Examples](#examples)
19+
- [Improving LLM <-> codebase interactions](#improving-llm---codebase-interactions)
20+
- [Examples](#codebase-interaction-examples)
21+
- [Use as a refactoring language / _diff_ format](#use-as-a-refactoring-language--_diff_-format)
22+
- [Tool Use](#tool-use)
23+
- [Run Python scripts to find the correct answer for certain types of problems](#run-python-scripts-to-find-the-correct-answer-for-certain-types-of-problems)
24+
- [Obtain the current local weather](#obtaining-the-current-local-weather)
25+
- [Get a list of image files in the current working dir](#get-a-list-of-image-files-in-the-current-working-dir)
26+
- [Take a peek at the user's screen and right-click on the user's clock widget](#take-a-peek-at-the-users-screen-and-right-click-on-the-users-clock-widget)
1727
- [Proposals](#proposals)
1828
- [Related](#related)
1929

2030
## What is CEDARScript?
2131

22-
A SQL-like language for efficient code analysis and transformations.
23-
24-
Most useful for AI code assistants.
25-
2632
It's a domain-specific language designed to improve how AI coding assistants interact with codebases and communicate their code modification intentions.
33+
2734
It provides a standardized way to express complex code modification and analysis operations, making it easier for
2835
AI-assisted development tools to understand and execute these tasks.
2936

37+
It also works as a gateway to external tools, so that the LLM can easily call local shell commands, external HTTP API endpoints, etc
38+
3039
## How to use it
3140

3241
1. You can easily [install a tool that supports CEDARScript](https://github.com/CEDARScript/cedarscript-integration-aider/blob/main/README.md#installation).
@@ -93,7 +102,7 @@ character- or line-level editing tasks.
93102
The CEDARScript runtime then handles all the minute details - precise line numbers, indentation counts, and syntax
94103
consistency - at zero token cost.
95104

96-
Let's get to know the two primary functions offered by CEDARScript:
105+
Let's get to know the 3 primary functions offered by CEDARScript:
97106

98107
1. **Code Analysis** to quickly get to know a large code base without having to read all contents of all files.
99108
- The CEDARScript runtime searches through the whole code base and only returns the relevant results,
@@ -111,6 +120,8 @@ so on, allowing the _CEDARScript commands_ to focus instead on higher levels of
111120
[identifier](grammar.js#L248-L251) names, [line](grammar.js#L243-L246) markers, relative
112121
[indentations](grammar.js#L306-L370) and [positions](grammar.js#L241-L300)
113122
(`AFTER`, `BEFORE`, `INTO` a function, its `BODY`, at the `TOP` or `BOTTOM` of it...)
123+
3. **[Tool Use](#tool-use)**: The runtime acts as a gateway through which the LLM can send and receive information.
124+
This opens up many possibilities.
114125

115126
## Key Features:
116127

@@ -167,18 +178,7 @@ This efficiency allows for more complex operations within token limits.
167178

168179
It provides a concise way to express complex code modification and analysis operations, making it easier for AI-assisted development tools to understand and perform these tasks.
169180

170-
### Use as a refactoring language / _diff_ format
171-
172-
One can use `CEDARScript` to concisely and unambiguously represent code modifications at a higher level than a standard diff format can.
173-
174-
IDEs can store the local history of files in CEDARScript format, and this can also be used for searches.
175-
176-
### Other Ideas to Explore
177-
- Code review systems for automated, in-depth code assessments
178-
- Automated code documentation and explanation tools
179-
- ...
180-
181-
## Examples
181+
#### Codebase Interaction Examples
182182

183183
Quick example: turn a method into a top-level function, using `CASE` filter with REGEX:
184184

@@ -230,6 +230,123 @@ UPDATE FILE "app/main.py" REPLACE FUNCTION "calculate_total" WITH ED '''
230230

231231
There are [many more examples](test/corpus) to look at...
232232

233+
### Use as a refactoring language / _diff_ format
234+
235+
One can use `CEDARScript` to concisely and unambiguously represent code modifications at a higher level than a standard diff format can.
236+
237+
IDEs can store the local history of files in CEDARScript format, and this can also be used for searches.
238+
239+
### Tool Use
240+
If **explicit** configuration is set, the [**CEDARScript runtime**](https://github.com/CEDARScript/cedarscript-editor-python) can act as
241+
a gateway through which an LLM can:
242+
1. Call local commands (`ls`, `grep`, `find`, `open`)
243+
2. Run scripts
244+
3. Call external HTTP API services
245+
4. See the user's screen and take control of the mouse and keyboard
246+
5. Possibilities are numerous...
247+
248+
The output from the external tool is captured and sent back to the LLM.
249+
250+
#### Tool Use Examples
251+
252+
#### Run Python scripts to find the correct answer for certain types of problems
253+
254+
```sql
255+
-- Suppose the LLM has difficulty counting letters...
256+
-- It can delegate the counting to a Python script:
257+
CALL LANGUAGE "python" WITH CONTENT '''
258+
print("Refrigerator".lower().count('r'))
259+
''';
260+
```
261+
262+
```sql
263+
-- Using env var
264+
CALL LANGUAGE "python"
265+
ENV CONTENT '''WORD=Refrigerator'''
266+
WITH CONTENT '''
267+
import os
268+
print(os.environ['WORD'].count('r'))
269+
''';
270+
```
271+
272+
```sql
273+
-- Using env var from the host computer
274+
CALL LANGUAGE "python"
275+
ENV INHERIT ONLY 'WORD'
276+
WITH CONTENT '''
277+
import os
278+
print(os.environ['WORD'].count('r'))
279+
''';
280+
```
281+
282+
#### Obtain the current local weather
283+
284+
```sql
285+
CALL COMMAND
286+
ENV INHERIT ONLY 'LOCATION' -- Get the current location from the host env var
287+
WITH CONTENT r'''
288+
#!/bin/bash
289+
curl -s "wttr.in/$LOCATION?format=%l:+%C+%t,+feels+like+%f,+%h+humidity"
290+
''';
291+
```
292+
293+
#### Get a list of image files in the current working dir
294+
295+
```sql
296+
CALL LANGUAGE "bash"
297+
WITH CONTENT r'''
298+
find . -type f -name "*.jpg"
299+
''';
300+
```
301+
302+
#### Take a peek at the user's screen and right-click on the user's clock widget
303+
304+
```sql
305+
CALL LANGUAGE "python"
306+
WITH CONTENT r'''
307+
import pyautogui
308+
import time
309+
from datetime import datetime
310+
import os
311+
312+
# Take screenshot and save it
313+
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
314+
screenshot_path = f"screen_{timestamp}.png"
315+
pyautogui.screenshot(screenshot_path)
316+
317+
# Print the path so the LLM can analyze the image
318+
print(f"IMAGE_PATH={screenshot_path}")
319+
''';
320+
```
321+
322+
After the LLM takes a look at the screenshot, it finds the clock and sends a mouse click:
323+
324+
```sql
325+
CALL LANGUAGE "python"
326+
ENV r'''
327+
X=1850 # Coordinates provided by LLM after image analysis
328+
Y=12 # Coordinates provided by LLM after image analysis
329+
'''
330+
WITH CONTENT r'''
331+
import pyautogui
332+
import os
333+
334+
# Get coordinates from environment
335+
x = int(os.environ['X'])
336+
y = int(os.environ['Y'])
337+
338+
# Move and click
339+
pyautogui.moveTo(x, y, duration=1.0)
340+
pyautogui.click()
341+
print(f"Clicked at ({x}, {y})")
342+
''';
343+
```
344+
345+
### Other Ideas to Explore
346+
- Code review systems for automated, in-depth code assessments
347+
- Automated code documentation and explanation tools
348+
- ...
349+
233350
# Proposals
234351
See [current proposals](proposals/)
235352

grammar.js

+33
Original file line numberDiff line numberDiff line change
@@ -150,12 +150,45 @@ module.exports = grammar({
150150
$.update_command,
151151
// DML (Read-Only)
152152
$.select_command,
153+
$.call_command,
153154
prec(-1, alias($.invalid_move_command, $.error))
154155
),
155156
invalid_move_command: $ => seq(
156157
'MOVE',
157158
choice('FILE', 'FUNCTION', 'METHOD', 'CLASS', 'VARIABLE'),
158159
),
160+
161+
call_command: $ => seq(
162+
'CALL',
163+
field('call_type', choice('COMMAND', seq('LANGUAGE', field('language', $.string)))),
164+
optional($.env_inherit_clause),
165+
repeat($.env_clause),
166+
'WITH', field('command_source', choice($.content_literal, $.singlefile_clause)),
167+
optional($.capture_clause)
168+
),
169+
env_inherit_clause: $ => prec.right(seq(
170+
'ENV',
171+
'INHERIT',
172+
field('inherit_mode', choice(
173+
'NONE', 'ALL', seq('ONLY', field('inherit_vars', $.string))
174+
))
175+
)),
176+
177+
env_clause: $ => seq(
178+
'ENV',
179+
field('env_vars', choice($.content_literal, $.singlefile_clause))
180+
),
181+
182+
// No precedence needed for capture_clause as it's straightforward
183+
capture_clause: $ => seq(
184+
'CAPTURE',
185+
field('capture_mode', choice(
186+
'ALL',
187+
'STDOUT',
188+
'STDERR'
189+
))
190+
),
191+
159192
create_command: $ => seq(
160193
'CREATE', $.singlefile_clause,
161194
'WITH', $.content_literal

proposals/capture-external-command-output/README.md

+16-3
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,19 @@ when solving complex mathematical challenges, e. g. https://epoch.ai/frontiermat
1414
```sql
1515
-- Capturing script output
1616

17+
-- Suppose the LLM has difficulty counting letters...
18+
-- It can delegate the counting to a Python script:
19+
CALL LANGUAGE "python" WITH CONTENT '''
20+
print("refrigerator".lower().count('r'))
21+
''';
22+
23+
CALL LANGUAGE "python"
24+
ENV CONTENT '''WORD=rrrrrrrracer'''
25+
WITH CONTENT '''
26+
import os
27+
print(os.environ['WORD'].count('r'))
28+
''';
29+
1730
CALL LANGUAGE "python"
1831
WITH CONTENT r'''
1932
import os
@@ -28,14 +41,14 @@ print(sys.version)
2841
''';
2942

3043
CALL COMMAND
31-
-- ENV MODE (ISOLATED* | INHERIT ONLY | INHERIT ALL)
44+
-- ENV INHERIT (NONE* | ONLY '<vars>' | ALL)
3245
ENV MODE INHERIT ONLY 'PATH, HOME, API_KEY'
3346
-- ENV (r'''<env-spec>''' | FILE "<path>")
34-
ENV r'''
47+
ENV CONTENT r'''
3548
OUTPUT_FORMAT=xml
3649
MAX_RESULTS=20
3750
'''
38-
CAPTURE STDOUT -- CAPTURE (*ALL | STDOUT | STDERR)
51+
CAPTURE STDOUT -- CAPTURE (ALL* | STDOUT | STDERR)
3952
-- WITH (CONTENT r'''<string>''' | FILE "<path>")
4053
WITH CONTENT r'''
4154
#!/bin/bash

0 commit comments

Comments
 (0)