<!-- Sema documentation — sdk-demo
     Sema is a new AI-native, neurosymbolic programming language most models
     have not been trained on. Full corpus: https://sema.49.12.246.95.sslip.io/llms-full.txt
     Install language support: https://sema.49.12.246.95.sslip.io/install-skill/ -->

# sdk-demo

> Embedding Sema via the SDK — driving the runtime from a host program.

> Embedding Sema via the SDK — driving the runtime from a host program.

Run it from `sema/`:

```bash
sema check examples/sdk-demo
SEMA_STRICT=1 sema run examples/sdk-demo
sema assure examples/sdk-demo --grade silver
```

## Source

### `src/main.sema`

```sema
# Using the Sema SDK (sdk/sema/ai.sema, vendored here as `ai`). Text runs on the
# built-in/GGUF engine out of the box; vision/OCR/STT/TTS bind small HF models
# via the Python bridge once `sema get-models` + the SDK extras are installed.

from sdk_demo.ai import ask, chat, embed_text, similarity

def weather(city: str) -> str !{}:
    sem "Get the weather for a city"
    return "sunny in " + city

test "SDK text, embedding, similarity, and tool surfaces are deterministic":
    ensure weather("Berlin") == "sunny in Berlin"
    first = embed_text("deterministic embedding probe")
    second = embed_text("deterministic embedding probe")
    ensure len(first) > 0
    ensure first == second
    ensure abs(similarity("same phrase", "same phrase") - 1.0) < 0.000000001
    ensure abs(similarity("red sunset", "crimson dusk") - similarity("crimson dusk", "red sunset")) < 0.000000001
    reply = chat("Say hello in one word.")
    answer = ask("what is the weather in Berlin?", [weather])
    ensure len(reply) > 0
    ensure len(answer) > 0

def main() -> None !{model.invoke, model.embed, ffi.call, observe.record}:
    # Text generation via the configured model (mock by default, real GGUF when
    # sema.toml points [models] generate at a real model — §5.43).
    log.info("chat", reply=chat("Say hello in one word."))
    # Embedding similarity (built-in embedder; a real one swaps in via config).
    log.info("similarity", score=similarity("a red sunset", "a crimson dusk"))
    # Tool-using agent (the SDK's ask() = model + your Sema functions as tools).
    log.info("agent", answer=ask("what is the weather in Berlin?", [weather]))
```

### `src/ai.sema`

```sema
# Sema SDK — the multimodal capability surface, written in Sema.
#
# The language does not ship blank: this module is the "standard AI library".
# Each function is a clean native Sema interface; the backend is chosen by the
# config/model registry (§5.38/§5.43). Text + embeddings run on the built-in /
# GGUF engines out of the box; vision/OCR/STT/TTS reuse small HuggingFace models
# through the Python bridge (§5.44) — we don't reinvent well-solved wheels, we
# bind them behind a Sema interface. Swap any backend in `sema.toml` (D48/D51).

import python
import tools

# ---- text ----------------------------------------------------------------

def chat(prompt: str) -> str !{model.invoke, ffi.call}:
    sem "Generate a natural-language response with the configured text model"
    return tools.run(prompt, []).get("answer")

def ask(question: str, toolset: list) -> str !{model.invoke, ffi.call}:
    sem "Answer a question, letting the model call the given Sema functions as tools"
    return tools.run(question, toolset).get("answer")

# ---- embeddings ----------------------------------------------------------

def embed_text(text: str) -> list[f64] !{model.embed}:
    sem "Embed text into a vector with the configured embedding model"
    return embed(text)

def similarity(a: str, b: str) -> f64 !{model.embed}:
    sem "Cosine similarity of two texts' embeddings"
    return (a ~= b).score

# ---- vision (reuses a small HF caption/vision model) ---------------------

def caption(image_path: str) -> str !{proc.run, fs.read}:
    sem "Describe an image in natural language"
    return python.call("sema_lang_sdk.vision", "caption", [image_path])

def vqa(image_path: str, question: str) -> str !{proc.run, fs.read}:
    sem "Answer a question about an image"
    return python.call("sema_lang_sdk.vision", "vqa", [image_path, question])

# ---- OCR -----------------------------------------------------------------

def ocr(image_path: str) -> str !{proc.run, fs.read}:
    sem "Extract text from an image (OCR)"
    return python.call("sema_lang_sdk.ocr", "read", [image_path])

# ---- speech --------------------------------------------------------------

def transcribe(audio_path: str) -> str !{proc.run, fs.read}:
    sem "Transcribe speech from an audio file to text (STT)"
    return python.call("sema_lang_sdk.stt", "transcribe", [audio_path])

def speak(text: str, out_path: str) -> str !{proc.run, fs.write}:
    sem "Synthesize speech audio from text (TTS); returns the output path"
    return python.call("sema_lang_sdk.tts", "speak", [text, out_path])
```

## Reflected API

# `ai`

# `def chat`

```sema
def chat(prompt: str) -> str !{model.invoke, ffi.call}
```

**Parameters**

| name | type |
|---|---|
| `prompt` | `str` |

**Returns** `str`

**Effects** `!{model.invoke, ffi.call}`

# `def ask`

```sema
def ask(question: str, toolset: list) -> str !{model.invoke, ffi.call}
```

**Parameters**

| name | type |
|---|---|
| `question` | `str` |
| `toolset` | `list` |

**Returns** `str`

**Effects** `!{model.invoke, ffi.call}`

# `def embed_text`

```sema
def embed_text(text: str) -> list[f64] !{model.embed}
```

**Parameters**

| name | type |
|---|---|
| `text` | `str` |

**Returns** `list[f64]`

**Effects** `!{model.embed}`

# `def similarity`

```sema
def similarity(a: str, b: str) -> f64 !{model.embed}
```

**Parameters**

| name | type |
|---|---|
| `a` | `str` |
| `b` | `str` |

**Returns** `f64`

**Effects** `!{model.embed}`

# `def caption`

```sema
def caption(image_path: str) -> str !{proc.run, fs.read}
```

**Parameters**

| name | type |
|---|---|
| `image_path` | `str` |

**Returns** `str`

**Effects** `!{proc.run, fs.read}`

# `def vqa`

```sema
def vqa(image_path: str, question: str) -> str !{proc.run, fs.read}
```

**Parameters**

| name | type |
|---|---|
| `image_path` | `str` |
| `question` | `str` |

**Returns** `str`

**Effects** `!{proc.run, fs.read}`

# `def ocr`

```sema
def ocr(image_path: str) -> str !{proc.run, fs.read}
```

**Parameters**

| name | type |
|---|---|
| `image_path` | `str` |

**Returns** `str`

**Effects** `!{proc.run, fs.read}`

# `def transcribe`

```sema
def transcribe(audio_path: str) -> str !{proc.run, fs.read}
```

**Parameters**

| name | type |
|---|---|
| `audio_path` | `str` |

**Returns** `str`

**Effects** `!{proc.run, fs.read}`

# `def speak`

```sema
def speak(text: str, out_path: str) -> str !{proc.run, fs.write}
```

**Parameters**

| name | type |
|---|---|
| `text` | `str` |
| `out_path` | `str` |

**Returns** `str`

**Effects** `!{proc.run, fs.write}`



# `main`

# `def weather`

```sema
def weather(city: str) -> str !{}
```

**Parameters**

| name | type |
|---|---|
| `city` | `str` |

**Returns** `str`

**Effects** `!{}`

# `def main`

```sema
def main() -> None !{model.invoke, model.embed, ffi.call, observe.record}
```

**Returns** `None`

**Effects** `!{model.invoke, model.embed, ffi.call, observe.record}`
