# core


<!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! -->

## Limits

Tool results consume model context. `MAX_TOOL_CHARS` limits one result.
Factories accept the limit as `mx` because the model sets the budget.

``` python
# a grep answers with more rows than a search, because an exact match is cheaper to read
assert MAX_GREP_HITS > MAX_HITS
assert MAX_TOOL_CHARS < 8_000 and MAX_FILE > MAX_TOOL_CHARS
test_eq((MAX_TOOL_CHARS, MAX_HITS, MAX_GREP_HITS, MAX_API, MAX_FILE), (6000, 20, 60, 200, 2_000_000))
```

Every search backend returns a
[`Hit`](https://vedicreader.github.io/shalya/core.html#hit) with the
path, line, symbol and matching text.

    /opt/hostedtoolcache/Python/3.12.14/x64/lib/python3.12/site-packages/usearch/__init__.py:131: UserWarning: Will download `usearch_sqlite` binary from GitHub.
      warnings.warn("Will download `usearch_sqlite` binary from GitHub.", UserWarning)

------------------------------------------------------------------------

<a
href="https://github.com/vedicreader/shalya/blob/main/shalya/core.py#L26"
target="_blank" style="float:right; font-size:smaller">source</a>

### Hit

``` python
def Hit(
    path, line:int=1, symbol:str='', text:str=''
):
```

*One search hit: path, line, symbol, text.*

``` python
h = Hit('shalya/core.py', 12, 'clip', 'def clip(s, n=MAX_TOOL_CHARS, more=\'\'):')
h.path, h.line, h.symbol
```

    ('shalya/core.py', 12, 'clip')

``` python
test_eq(repr(h), "shalya/core.py:12  clip  def clip(s, n=MAX_TOOL_CHARS, more=''):")
```

## Failure

Tool failures start with `ERROR:`.
[`failed`](https://vedicreader.github.io/shalya/core.html#failed) checks
this prefix. Returning `err(...)` lets the model inspect a failure
without ending the turn.

------------------------------------------------------------------------

<a
href="https://github.com/vedicreader/shalya/blob/main/shalya/core.py#L44"
target="_blank" style="float:right; font-size:smaller">source</a>

### failed

``` python
def failed(
    result
):
```

*Whether a tool result starts with `ERROR:`.*

------------------------------------------------------------------------

<a
href="https://github.com/vedicreader/shalya/blob/main/shalya/core.py#L40"
target="_blank" style="float:right; font-size:smaller">source</a>

### err

``` python
def err(
    what, e:NoneType=None
):
```

*One tool failure, spelled the way every other tool spells it.*

------------------------------------------------------------------------

<a
href="https://github.com/vedicreader/shalya/blob/main/shalya/core.py#L36"
target="_blank" style="float:right; font-size:smaller">source</a>

### host_err

``` python
def host_err(
    e
):
```

*A caught exception, for a user-facing surface.*

------------------------------------------------------------------------

<a
href="https://github.com/vedicreader/shalya/blob/main/shalya/core.py#L34"
target="_blank" style="float:right; font-size:smaller">source</a>

### HostError

``` python
def HostError(
    *args, **kwargs
):
```

*A host refusal.*

``` python
try: raise HostError('path is outside the open folders: /etc/passwd')
except HostError as e: shown = host_err(e)
shown
```

    'HostError: path is outside the open folders: /etc/passwd'

``` python
test_eq(shown, 'HostError: path is outside the open folders: /etc/passwd')
test_eq(host_err(KeyError('nope')), "KeyError: 'nope'")
test_eq(err('could not read', HostError('no such file')), 'ERROR: could not read: HostError: no such file')
test_eq(ERR, 'ERROR: ')
```

``` python
try: json.loads('{not json}')
except Exception as e: msg = err('cannot read the edits', e)
msg
```

    'ERROR: cannot read the edits: JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)'

``` python
test_eq(failed(msg), True)
test_eq(failed('ERROR was not the problem'), False)
test_eq(err('no such file'), 'ERROR: no such file')
```

## Clipping

[`clip`](https://vedicreader.github.io/shalya/core.html#clip) truncates
at a line boundary.
[`clip_lines`](https://vedicreader.github.io/shalya/core.html#clip_lines)
also reports the next line, which supports paging.

------------------------------------------------------------------------

<a
href="https://github.com/vedicreader/shalya/blob/main/shalya/core.py#L49"
target="_blank" style="float:right; font-size:smaller">source</a>

### clip

``` python
def clip(
    s, n:int=6000, more:str=''
):
```

*Truncate a tool result to `n` chars. A caller with a way to resume
passes it as `more`.*

``` python
print(clip('one\ntwo\nthree\nfour\nfive\n', 12))
```

    one
    two
    thre…[truncated: 12 of 24 chars shown]

``` python
test_eq(clip('short', 12), 'short')
test_eq(clip('one\ntwo\nthree\nfour', 12).splitlines()[0], 'one')
```

A line longer than the budget is truncated by character count. The
notice reports the original and shown lengths without offering the same
line as a resume point.

------------------------------------------------------------------------

<a
href="https://github.com/vedicreader/shalya/blob/main/shalya/core.py#L60"
target="_blank" style="float:right; font-size:smaller">source</a>

### clip_lines

``` python
def clip_lines(
    lines, start:int=1, n:int=6000, more:str='', empty:str='(nothing)'
):
```

*Render `lines` within the budget, and say which line to resume from.*

``` python
print(clip_lines(['def a(): pass', 'def b(): pass', 'def c(): pass'], n=30,
                more='read from line {next}'))
```

    def a(): pass
    def b(): pass
    …[1 more line(s) not shown. read from line 3]

``` python
test_eq(clip_lines([], empty='(no matches)'), '(no matches)')
test_eq(clip_lines(['a', 'b'], n=100), 'a\nb')
long = clip_lines(['x' * 50], n=20)
assert long.startswith('x' * 19) and '50 chars' in long, long
```

## Edits

Tool calls carry edits as JSON.
[`cmds`](https://vedicreader.github.io/shalya/core.html#cmds) parses
exhash commands.
[`edits`](https://vedicreader.github.io/shalya/core.html#edits) parses
exact-text replacements. Both reject ambiguous input with an actionable
error.

------------------------------------------------------------------------

<a
href="https://github.com/vedicreader/shalya/blob/main/shalya/core.py#L80"
target="_blank" style="float:right; font-size:smaller">source</a>

### cmds

``` python
def cmds(
    commands
):
```

*Models emit JSON and exhash wants tuples, nested ones included:
`[[...]]` becomes `[(...)]`.*

``` python
cmds('[["12|a1b2|", "s", "old", "new"], ["30|9f3c|", "a", "appended"]]')
```

    [('12|a1b2|', 's', 'old', 'new'), ('30|9f3c|', 'a', 'appended')]

``` python
test_eq(cmds([['1|ab|', 'd']]), [('1|ab|', 'd')])
test_fail(lambda: cmds('{"not": "a list"}'), contains='must be a JSON list')
test_fail(lambda: cmds('["bare string"]'), contains='must be an array')
```

[`edits`](https://vedicreader.github.io/shalya/core.html#edits) takes
the exact-text form in any of its three spellings.
[`apply_edits`](https://vedicreader.github.io/shalya/core.html#apply_edits)
holds the refusals. Each one names the edit that is wrong and what to do
about it. A match that is not unique needs more context. Two edits over
the same span need merging.

------------------------------------------------------------------------

<a
href="https://github.com/vedicreader/shalya/blob/main/shalya/core.py#L104"
target="_blank" style="float:right; font-size:smaller">source</a>

### apply_edits

``` python
def apply_edits(
    text, es
):
```

*Apply exact-text edits to `text`, or raise saying which one is wrong
and why.*

------------------------------------------------------------------------

<a
href="https://github.com/vedicreader/shalya/blob/main/shalya/core.py#L90"
target="_blank" style="float:right; font-size:smaller">source</a>

### edits

``` python
def edits(
    es
):
```

*A JSON string, `{'oldText','newText'}` dicts, or `[old, new]` pairs:
all three are unambiguous.*

``` python
before = 'def greet(name):\n    return "hello " + name\n'
after = apply_edits(before, edits('[{"oldText": "hello", "newText": "howdy"}]'))
after
```

    'def greet(name):\n    return "howdy " + name\n'

``` python
test_eq(edits([['a', 'b']]), [('a', 'b')])
test_eq(edits({'oldText': 'a', 'newText': 'b'}), [('a', 'b')])
test_eq(after, 'def greet(name):\n    return "howdy " + name\n')
```

The three refusals, on real text. Each message tells the model what to
change rather than that it failed.

``` python
test_fail(lambda: apply_edits(before, [('name', 'who')]), contains='matches 2 places')
test_fail(lambda: apply_edits(before, [('nowhere', 'x')]), contains='not found')
test_fail(lambda: apply_edits(before, [('def greet', 'def hi'), ('greet(name)', 'hi(n)')]),
          contains='overlap')
```

Edit approvals carry a unified diff.

------------------------------------------------------------------------

<a
href="https://github.com/vedicreader/shalya/blob/main/shalya/core.py#L126"
target="_blank" style="float:right; font-size:smaller">source</a>

### diff_text

``` python
def diff_text(
    before, after, path:str='file'
):
```

*Return a unified diff.*

``` python
print(diff_text(before, after, 'greet.py'))
```

    --- a/greet.py
    +++ b/greet.py
    @@ -1,2 +1,2 @@
     def greet(name):
    -    return "hello " + name
    +    return "howdy " + name

``` python
assert '-    return "hello " + name' in diff_text(before, after)
assert diff_text(before, before) == ''
```

## Which tools write

Writes require approval. `@writes` marks a callable; `WRITE_TOOLS`
provides the same fact when a caller has only its name. The tests
require both representations to agree.

------------------------------------------------------------------------

<a
href="https://github.com/vedicreader/shalya/blob/main/shalya/core.py#L163"
target="_blank" style="float:right; font-size:smaller">source</a>

### summarise

``` python
def summarise(
    tool, args:NoneType=None
):
```

*The imperative one-liner for a call: what a person would say they just
did.*

------------------------------------------------------------------------

<a
href="https://github.com/vedicreader/shalya/blob/main/shalya/core.py#L155"
target="_blank" style="float:right; font-size:smaller">source</a>

### summary

``` python
def summary(
    fn
):
```

*Mark the one line a person reads after this tool runs. `fn` is given
the call’s arguments.*

------------------------------------------------------------------------

<a
href="https://github.com/vedicreader/shalya/blob/main/shalya/core.py#L149"
target="_blank" style="float:right; font-size:smaller">source</a>

### one_line

``` python
def one_line(
    v, n:int=90
):
```

*One line of a value, short enough to sit in a list.*

------------------------------------------------------------------------

<a
href="https://github.com/vedicreader/shalya/blob/main/shalya/core.py#L145"
target="_blank" style="float:right; font-size:smaller">source</a>

### has_effect

``` python
def has_effect(
    t
):
```

*Whether `t` acts. Orthogonal to
[`is_write`](https://vedicreader.github.io/shalya/core.html#is_write):
these are the effects approval does not gate.*

------------------------------------------------------------------------

<a
href="https://github.com/vedicreader/shalya/blob/main/shalya/core.py#L140"
target="_blank" style="float:right; font-size:smaller">source</a>

### acts

``` python
def acts(
    f
):
```

*Mark a tool that acts without writing a file the user owns.*

------------------------------------------------------------------------

<a
href="https://github.com/vedicreader/shalya/blob/main/shalya/core.py#L136"
target="_blank" style="float:right; font-size:smaller">source</a>

### is_write

``` python
def is_write(
    t
):
```

*Whether `t` is a tool that changes something.*

------------------------------------------------------------------------

<a
href="https://github.com/vedicreader/shalya/blob/main/shalya/core.py#L131"
target="_blank" style="float:right; font-size:smaller">source</a>

### writes

``` python
def writes(
    f
):
```

*Mark a tool as one that changes something. `Approvals` puts these in
front of a person.*

``` python
@writes
def create_file(path, text): return f'wrote {path}'
def view_file(path): return 'contents'
is_write(create_file), is_write(view_file)
```

    (True, False)

``` python
test_eq(is_write(create_file), True)
test_eq(is_write(view_file), False)
test_eq(create_file.__name__ in WRITE_TOOLS, True)
test_eq(sorted(GIT_TOOLS), sorted(set(GIT_READ_TOOLS) | GIT_WRITE_TOOLS))
```
