tiny-agent-ai 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,155 @@
1
+ # tiny-agent
2
+
3
+ Minimal, extension-based AI agent. The core is ~200 lines — just the loop and types. Everything else is an extension.
4
+
5
+ ## Usage
6
+
7
+ ```bash
8
+ bun add tiny-agent-ai
9
+ ```
10
+
11
+ ```typescript
12
+ import { Agent, OpenAIProvider, toolsExtension, loopDetectionExtension } from 'tiny-agent-ai'
13
+ import type { Tool } from 'tiny-agent-ai'
14
+
15
+ // Define a custom tool
16
+ const weatherTool: Tool = {
17
+ definition: {
18
+ name: 'get_weather',
19
+ description: 'Get current weather for a city',
20
+ parameters: {
21
+ type: 'object',
22
+ properties: { city: { type: 'string', description: 'City name' } },
23
+ required: ['city'],
24
+ },
25
+ },
26
+ async execute(input) {
27
+ const res = await fetch(`https://wttr.in/${input.city}?format=j1`)
28
+ const data = await res.json()
29
+ return { output: JSON.stringify(data.current_condition[0]) }
30
+ },
31
+ }
32
+
33
+ const provider = new OpenAIProvider(process.env.OPENAI_API_KEY!, 'gpt-4o')
34
+
35
+ const agent = new Agent({
36
+ provider,
37
+ systemPrompt: 'You are a helpful assistant with access to weather data.',
38
+ extensions: [
39
+ { name: 'weather', tools: [weatherTool] },
40
+ toolsExtension(),
41
+ loopDetectionExtension(),
42
+ ],
43
+ })
44
+
45
+ for await (const event of agent.run('What is the weather in Berlin?')) {
46
+ if (event.type === 'text_delta') process.stdout.write(event.text)
47
+ }
48
+ ```
49
+
50
+ The `Agent` class takes a provider, a system prompt, and an array of extensions. No config files, no env var conventions, no DI — you wire it however you want.
51
+
52
+ ## Architecture
53
+
54
+ The core (`packages/core/`) has three files:
55
+
56
+ - **`types.ts`** — `Message`, `Tool`, `Provider`, `Extension`, `MessageStore` interfaces
57
+ - **`agent.ts`** — The loop: stream LLM → parse tool calls → run hooks → execute tools → repeat
58
+ - **`index.ts`** — Barrel exports
59
+
60
+ The loop:
61
+
62
+ 1. Push user message, call `beforeSend` hooks, stream from provider
63
+ 2. Collect text deltas and tool call chunks into a complete assistant message
64
+ 3. If no tool calls → `onTurnDone`, yield `turn_done`, return
65
+ 4. For each tool call → `beforeToolCall` (can block/inject) → execute → `afterToolCall` (can transform result)
66
+ 5. Append tool results, go to step 1
67
+
68
+ ## Extension API
69
+
70
+ ```typescript
71
+ interface Extension {
72
+ name: string
73
+ tools?: Tool[]
74
+ beforeSend?(messages: Message[]): Message[] | Promise<Message[]>
75
+ beforeToolCall?(toolCall: ToolCall): boolean | { inject: Message } | Promise<...>
76
+ afterToolCall?(toolCall: ToolCall, result: ToolResult): ToolResult | Promise<ToolResult>
77
+ onTurnDone?(messages: Message[]): void | Promise<void>
78
+ }
79
+ ```
80
+
81
+ Extensions run in array order. Put safety extensions before tool extensions.
82
+
83
+ Built-in:
84
+ - **toolsExtension** — read, write, edit, glob, grep, bash
85
+ - **loopDetectionExtension** — breaks infinite tool-call loops
86
+ - **compactionExtension** — summarizes old messages when context fills up
87
+ - **taskExtension** — delegates subtasks to isolated sub-agents
88
+
89
+ See [`packages/core/README.md`](packages/core/README.md) for detailed extension docs.
90
+
91
+ ## Providers
92
+
93
+ The core defines a `Provider` interface — anything that implements `stream()` works:
94
+
95
+ ```typescript
96
+ interface Provider {
97
+ name: string
98
+ stream(messages, tools, systemPrompt, maxTokens): AsyncIterable<ProviderChunk>
99
+ }
100
+ ```
101
+
102
+ Included: `OpenAIProvider` (works with any OpenAI-compatible API) and `AnthropicProvider`. Write your own for Gemini, Ollama, or anything else.
103
+
104
+ ## Message Persistence
105
+
106
+ The `Agent` accepts an optional `store: MessageStore` for persistence. The interface is minimal:
107
+
108
+ ```typescript
109
+ interface MessageStore {
110
+ getMessages(): Message[]
111
+ append(message: Message): void
112
+ }
113
+ ```
114
+
115
+ The included `Session` class (`packages/session/`) is a JSONL-based implementation. You can swap it for Redis, SQLite, a database — whatever fits your use case.
116
+
117
+ ## Packages
118
+
119
+ ```
120
+ packages/core/ Agent loop + types (zero deps)
121
+ packages/tiny-agent/ Barrel — single import (`tiny-agent-ai` on npm)
122
+ packages/providers/openai/ OpenAI-compatible provider (included)
123
+ packages/providers/anthropic/ Native Anthropic provider (included)
124
+ packages/extensions/tools/ Filesystem + bash tools
125
+ packages/extensions/loop-detection/ Breaks infinite loops
126
+ packages/extensions/compaction/ Context window management
127
+ packages/extensions/task/ Sub-agent delegation
128
+ packages/session/ JSONL MessageStore implementation (example)
129
+ packages/examples/cli/ Interactive REPL with slash commands
130
+ packages/examples/web/ SSE server + chat UI
131
+ ```
132
+
133
+ ## Running the Examples
134
+
135
+ ```bash
136
+ bun install
137
+ cd packages/examples/cli # or web
138
+ cp agent.config.example.json agent.config.json
139
+ # Add your API key and model
140
+
141
+ bun run dev
142
+ ```
143
+
144
+ See each example's README for details.
145
+
146
+ ## Development
147
+
148
+ ```bash
149
+ bun run typecheck # Type-check all packages
150
+ bun run format # Prettier
151
+ ```
152
+
153
+ ## License
154
+
155
+ MIT
package/package.json ADDED
@@ -0,0 +1,32 @@
1
+ {
2
+ "name": "tiny-agent-ai",
3
+ "version": "0.1.2",
4
+ "description": "Minimal, extension-based AI agent. ~200 lines core, everything else is an extension.",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/xy69/tiny-agent"
10
+ },
11
+ "keywords": ["ai", "agent", "llm", "coding-agent", "openai", "anthropic", "tools"],
12
+ "exports": {
13
+ ".": "./src/index.ts"
14
+ },
15
+ "scripts": {
16
+ "typecheck": "tsc --noEmit"
17
+ },
18
+ "dependencies": {
19
+ "@tiny-agent/core": "workspace:*",
20
+ "@tiny-agent/ext-tools": "workspace:*",
21
+ "@tiny-agent/ext-compaction": "workspace:*",
22
+ "@tiny-agent/ext-loop-detection": "workspace:*",
23
+ "@tiny-agent/ext-task": "workspace:*",
24
+ "@tiny-agent/provider-openai": "workspace:*",
25
+ "@tiny-agent/provider-anthropic": "workspace:*",
26
+ "@tiny-agent/session": "workspace:*"
27
+ },
28
+ "devDependencies": {
29
+ "typescript": "catalog:",
30
+ "@types/bun": "catalog:"
31
+ }
32
+ }
package/src/index.ts ADDED
@@ -0,0 +1,21 @@
1
+ export { Agent } from '@tiny-agent/core'
2
+ export type { AgentOptions } from '@tiny-agent/core'
3
+ export type {
4
+ Extension,
5
+ Tool,
6
+ ToolDefinition,
7
+ ToolResult,
8
+ MessageStore,
9
+ Provider,
10
+ StreamEvent,
11
+ Message,
12
+ ProviderChunk,
13
+ ToolCall,
14
+ } from '@tiny-agent/core'
15
+ export { Session } from '@tiny-agent/session'
16
+ export { OpenAIProvider } from '@tiny-agent/provider-openai'
17
+ export { AnthropicProvider } from '@tiny-agent/provider-anthropic'
18
+ export { toolsExtension } from '@tiny-agent/ext-tools'
19
+ export { compactionExtension } from '@tiny-agent/ext-compaction'
20
+ export { loopDetectionExtension } from '@tiny-agent/ext-loop-detection'
21
+ export { taskExtension } from '@tiny-agent/ext-task'
package/tsconfig.json ADDED
@@ -0,0 +1,4 @@
1
+ {
2
+ "extends": "../../tsconfig.base.json",
3
+ "include": ["src"]
4
+ }