jamjet 0.1.0__tar.gz
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.
- jamjet-0.1.0/.gitignore +82 -0
- jamjet-0.1.0/PKG-INFO +342 -0
- jamjet-0.1.0/README.md +323 -0
- jamjet-0.1.0/jamjet/__init__.py +34 -0
- jamjet-0.1.0/jamjet/agents/__init__.py +1 -0
- jamjet-0.1.0/jamjet/cli/__init__.py +0 -0
- jamjet-0.1.0/jamjet/cli/main.py +1000 -0
- jamjet-0.1.0/jamjet/client.py +158 -0
- jamjet-0.1.0/jamjet/compiler/__init__.py +9 -0
- jamjet-0.1.0/jamjet/compiler/strategies.py +525 -0
- jamjet-0.1.0/jamjet/eval/__init__.py +33 -0
- jamjet-0.1.0/jamjet/eval/dataset.py +82 -0
- jamjet-0.1.0/jamjet/eval/runner.py +216 -0
- jamjet-0.1.0/jamjet/eval/scorers.py +250 -0
- jamjet-0.1.0/jamjet/memory/__init__.py +1 -0
- jamjet-0.1.0/jamjet/models/__init__.py +1 -0
- jamjet-0.1.0/jamjet/tools/__init__.py +3 -0
- jamjet-0.1.0/jamjet/tools/decorators.py +149 -0
- jamjet-0.1.0/jamjet/workflow/__init__.py +5 -0
- jamjet-0.1.0/jamjet/workflow/graph.py +74 -0
- jamjet-0.1.0/jamjet/workflow/ir_compiler.py +380 -0
- jamjet-0.1.0/jamjet/workflow/nodes.py +67 -0
- jamjet-0.1.0/jamjet/workflow/types.py +31 -0
- jamjet-0.1.0/jamjet/workflow/workflow.py +134 -0
- jamjet-0.1.0/pyproject.toml +59 -0
- jamjet-0.1.0/tests/__init__.py +0 -0
- jamjet-0.1.0/tests/test_strategy_compiler.py +348 -0
- jamjet-0.1.0/tests/test_workflow.py +148 -0
- jamjet-0.1.0/uv.lock +612 -0
jamjet-0.1.0/.gitignore
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# Rust
|
|
2
|
+
/target/
|
|
3
|
+
runtime/target/
|
|
4
|
+
Cargo.lock
|
|
5
|
+
|
|
6
|
+
# Python
|
|
7
|
+
__pycache__/
|
|
8
|
+
*.py[cod]
|
|
9
|
+
*.egg-info/
|
|
10
|
+
.venv/
|
|
11
|
+
sdk/python/.venv/
|
|
12
|
+
dist/
|
|
13
|
+
.mypy_cache/
|
|
14
|
+
.ruff_cache/
|
|
15
|
+
.pytest_cache/
|
|
16
|
+
|
|
17
|
+
# JamJet local runtime
|
|
18
|
+
.jamjet/
|
|
19
|
+
*.db
|
|
20
|
+
*.db-shm
|
|
21
|
+
*.db-wal
|
|
22
|
+
|
|
23
|
+
# Environment
|
|
24
|
+
.env
|
|
25
|
+
.env.*
|
|
26
|
+
!.env.example
|
|
27
|
+
|
|
28
|
+
# Editor
|
|
29
|
+
.idea/
|
|
30
|
+
.vscode/
|
|
31
|
+
*.swp
|
|
32
|
+
*.swo
|
|
33
|
+
|
|
34
|
+
# OS
|
|
35
|
+
.DS_Store
|
|
36
|
+
Thumbs.db
|
|
37
|
+
|
|
38
|
+
# Benchmarks / profiling
|
|
39
|
+
flamegraph.svg
|
|
40
|
+
perf.data*
|
|
41
|
+
|
|
42
|
+
# Internal planning docs (not for public repo)
|
|
43
|
+
progress-tracker.md
|
|
44
|
+
REQUIREMENTS.md
|
|
45
|
+
launch-plan.md
|
|
46
|
+
|
|
47
|
+
# Local AI/editor agent config
|
|
48
|
+
.claude/*.local.*
|
|
49
|
+
.claude/settings.local.json
|
|
50
|
+
.cursor/
|
|
51
|
+
.copilot/
|
|
52
|
+
|
|
53
|
+
# Secrets and credentials
|
|
54
|
+
*.pem
|
|
55
|
+
*.key
|
|
56
|
+
*.p12
|
|
57
|
+
*.pfx
|
|
58
|
+
*.service-account.json
|
|
59
|
+
credentials*.json
|
|
60
|
+
.envrc
|
|
61
|
+
.secrets*
|
|
62
|
+
|
|
63
|
+
# Infrastructure state and local cloud env
|
|
64
|
+
.terraform/
|
|
65
|
+
*.tfstate
|
|
66
|
+
*.tfstate.*
|
|
67
|
+
*.tfvars
|
|
68
|
+
.pulumi/
|
|
69
|
+
.azd/
|
|
70
|
+
|
|
71
|
+
# Coverage, logs, temp artifacts
|
|
72
|
+
coverage/
|
|
73
|
+
htmlcov/
|
|
74
|
+
.coverage
|
|
75
|
+
.coverage.*
|
|
76
|
+
*.log
|
|
77
|
+
logs/
|
|
78
|
+
tmp/
|
|
79
|
+
.tmp/
|
|
80
|
+
*.pid
|
|
81
|
+
*.sqlite
|
|
82
|
+
*.sqlite3
|
jamjet-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: jamjet
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: JamJet Python SDK — agent-native workflow authoring and CLI
|
|
5
|
+
License: Apache-2.0
|
|
6
|
+
Requires-Python: >=3.11
|
|
7
|
+
Requires-Dist: anyio>=4.0
|
|
8
|
+
Requires-Dist: httpx>=0.27
|
|
9
|
+
Requires-Dist: pydantic>=2.0
|
|
10
|
+
Requires-Dist: pyyaml>=6.0
|
|
11
|
+
Requires-Dist: rich>=13.0
|
|
12
|
+
Requires-Dist: typer>=0.12
|
|
13
|
+
Provides-Extra: dev
|
|
14
|
+
Requires-Dist: mypy>=1.10; extra == 'dev'
|
|
15
|
+
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
|
|
16
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
17
|
+
Requires-Dist: ruff>=0.4; extra == 'dev'
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
|
|
20
|
+
# JamJet
|
|
21
|
+
|
|
22
|
+
> **The agent-native runtime — built for performance, designed for interoperability, reliable enough for production.**
|
|
23
|
+
|
|
24
|
+
[](https://github.com/jamjet-labs/jamjet/actions)
|
|
25
|
+
[](LICENSE)
|
|
26
|
+
[](https://rustup.rs)
|
|
27
|
+
[](https://python.org)
|
|
28
|
+
[](https://jamjet.dev/docs)
|
|
29
|
+
|
|
30
|
+
JamJet is a **performance-first, agent-native runtime and framework** for building reliable, interoperable AI agent systems. It is not another prompt wrapper or thin agent SDK — it is a **production-grade orchestration substrate** for agents that need to work, not just demo.
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Why JamJet?
|
|
35
|
+
|
|
36
|
+
| Problem | JamJet's answer |
|
|
37
|
+
|---------|----------------|
|
|
38
|
+
| Fragile agent runs that lose state on crash | **Durable graph execution** with event sourcing and crash recovery |
|
|
39
|
+
| No way to pause for human approval | **Human-in-the-loop** as a first-class workflow primitive |
|
|
40
|
+
| Agents siloed in their own framework | **Native MCP + A2A** — interoperate with any agent, any framework |
|
|
41
|
+
| Slow Python orchestration at scale | **Rust core** for scheduling, state, concurrency; Python for authoring |
|
|
42
|
+
| Weak observability, no replay | **Full event timeline**, replay from any checkpoint |
|
|
43
|
+
| No standard agent identity | **Agent Cards** — every agent is addressable, discoverable, composable |
|
|
44
|
+
| Inconsistent tool contracts | **Typed schemas everywhere** — Pydantic, TypedDict, JSON Schema |
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## How JamJet compares
|
|
49
|
+
|
|
50
|
+
> As of March 2026. All frameworks evolve quickly — check their docs for the latest.
|
|
51
|
+
|
|
52
|
+
| Capability | JamJet | LangChain | AutoGen | CrewAI | BeeAI |
|
|
53
|
+
|------------|--------|-----------|---------|--------|-------|
|
|
54
|
+
| **Default model** | Agent-first + strategy | Chain / LCEL | Conversational agents | Role-based crew | Agent loop |
|
|
55
|
+
| **Durable execution** | ✅ event-sourced; crash-safe resume | ❌ ephemeral | ❌ ephemeral | ❌ ephemeral | ❌ ephemeral |
|
|
56
|
+
| **Human-in-the-loop** | ✅ first-class primitive | 🟡 callback hooks | 🟡 first-class for conversational flows | 🟡 manual | ❌ |
|
|
57
|
+
| **MCP support** | ✅ client + server | 🟡 client only | 🟡 client only | 🟡 client only | 🟡 client only |
|
|
58
|
+
| **A2A protocol** | ✅ client + server | ❌ | ❌ | ❌ | ❌ |
|
|
59
|
+
| **Pluggable reasoning strategies** | ✅ react, plan-and-execute, critic, reflection, consensus, debate | ❌ manual wiring | 🟡 user-built | 🟡 role-based tasks | 🟡 user-built |
|
|
60
|
+
| **Enforced cost/iteration limits** | ✅ compile-time guards | ❌ | 🟡 partial | 🟡 partial | ❌ |
|
|
61
|
+
| **Typed state schemas** | ✅ Pydantic / TypedDict / JSON Schema | 🟡 optional | 🟡 optional | 🟡 partial | 🟡 partial |
|
|
62
|
+
| **Built-in observability** | ✅ OTel GenAI, full event timeline, replay | 🟡 LangSmith (external) | ❌ | ❌ | ❌ |
|
|
63
|
+
| **Agent identity + discovery** | ✅ Agent Cards, A2A discovery | ❌ | ❌ | ❌ | 🟡 framework-level discovery |
|
|
64
|
+
| **Runtime language** | Rust core + Python authoring | Python | Python | Python | TypeScript |
|
|
65
|
+
| **Scheduler / throughput** | ✅ Rust async scheduler; low-overhead worker pool | 🟡 Python asyncio; GIL-bound | 🟡 Python asyncio; message-passing overhead | 🟡 Python; sequential by default | 🟡 Node.js event loop |
|
|
66
|
+
| **Deployment model** | Long-running server (local or cloud) | Library (in-process) | Library (in-process) | Library (in-process) | Library (in-process) |
|
|
67
|
+
| **Best for** | Production multi-agent systems needing durability and interop | Rapid prototyping, LLM chains | Conversational multi-agent apps | Role-based collab agents | TypeScript agentic apps |
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## Key Features
|
|
72
|
+
|
|
73
|
+
**Durable graph workflows** — every step is checkpointed; crash the runtime and execution resumes exactly where it left off.
|
|
74
|
+
|
|
75
|
+
**Native MCP + A2A** — connect to any MCP server, expose your tools as an MCP server, delegate to or serve external agents via A2A.
|
|
76
|
+
|
|
77
|
+
**Agent-native identity** — every agent has a URI, an Agent Card describing its capabilities, and a managed lifecycle.
|
|
78
|
+
|
|
79
|
+
**Human-in-the-loop** — pause any workflow for human approval or input as a first-class primitive.
|
|
80
|
+
|
|
81
|
+
**Configurable autonomy** — from strict deterministic graph execution to bounded autonomous agents operating within defined budgets.
|
|
82
|
+
|
|
83
|
+
**Typed schemas everywhere** — Pydantic, TypedDict, JSON Schema. No stringly-typed state.
|
|
84
|
+
|
|
85
|
+
**Distributed workers** — horizontal scale with lease semantics, retry policies, and queue isolation by workload type.
|
|
86
|
+
|
|
87
|
+
**Python-friendly authoring** — define workflows with Python decorators or YAML; both compile to the same runtime graph.
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## Quick Start
|
|
92
|
+
|
|
93
|
+
**Requirements:** Python 3.11+
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
# Install the CLI (runtime binary included)
|
|
97
|
+
pip install jamjet
|
|
98
|
+
|
|
99
|
+
# Option A — scaffold a new project
|
|
100
|
+
jamjet init my-agent-project
|
|
101
|
+
cd my-agent-project
|
|
102
|
+
|
|
103
|
+
# Option B — add JamJet to an existing project (works like git init)
|
|
104
|
+
cd my-existing-project
|
|
105
|
+
jamjet init
|
|
106
|
+
|
|
107
|
+
# Start local dev runtime (SQLite, embedded — no server setup needed)
|
|
108
|
+
jamjet dev
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
In another terminal:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
# Run the example workflow
|
|
115
|
+
jamjet run examples/basic_tool_flow
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Hello World — Python
|
|
119
|
+
|
|
120
|
+
```python
|
|
121
|
+
from jamjet import Workflow, tool
|
|
122
|
+
from pydantic import BaseModel
|
|
123
|
+
|
|
124
|
+
class SearchResult(BaseModel):
|
|
125
|
+
summary: str
|
|
126
|
+
sources: list[str]
|
|
127
|
+
|
|
128
|
+
@tool
|
|
129
|
+
async def web_search(query: str) -> SearchResult:
|
|
130
|
+
# your implementation here
|
|
131
|
+
...
|
|
132
|
+
|
|
133
|
+
workflow = Workflow("research")
|
|
134
|
+
|
|
135
|
+
@workflow.state
|
|
136
|
+
class ResearchState(BaseModel):
|
|
137
|
+
question: str
|
|
138
|
+
result: SearchResult | None = None
|
|
139
|
+
|
|
140
|
+
@workflow.step
|
|
141
|
+
async def search(state: ResearchState) -> ResearchState:
|
|
142
|
+
result = await web_search(query=state.question)
|
|
143
|
+
return state.model_copy(update={"result": result})
|
|
144
|
+
|
|
145
|
+
@workflow.step
|
|
146
|
+
async def summarize(state: ResearchState) -> ResearchState:
|
|
147
|
+
# model call here
|
|
148
|
+
...
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### Hello World — YAML
|
|
152
|
+
|
|
153
|
+
```yaml
|
|
154
|
+
# workflow.yaml
|
|
155
|
+
workflow:
|
|
156
|
+
id: research
|
|
157
|
+
version: 0.1.0
|
|
158
|
+
state_schema: schemas.ResearchState
|
|
159
|
+
start: search
|
|
160
|
+
|
|
161
|
+
nodes:
|
|
162
|
+
search:
|
|
163
|
+
type: tool
|
|
164
|
+
tool_ref: tools.web_search
|
|
165
|
+
input:
|
|
166
|
+
query: "{{ state.question }}"
|
|
167
|
+
output_schema: schemas.SearchResult
|
|
168
|
+
next: summarize
|
|
169
|
+
|
|
170
|
+
summarize:
|
|
171
|
+
type: model
|
|
172
|
+
model: default_chat
|
|
173
|
+
prompt: prompts/summarize.md
|
|
174
|
+
output_schema: schemas.Summary
|
|
175
|
+
next: end
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
jamjet validate workflow.yaml
|
|
180
|
+
jamjet run workflow.yaml --input '{"question": "What is JamJet?"}'
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### Connecting to an MCP Server
|
|
184
|
+
|
|
185
|
+
```yaml
|
|
186
|
+
# agents.yaml
|
|
187
|
+
agents:
|
|
188
|
+
researcher:
|
|
189
|
+
model: default_chat
|
|
190
|
+
mcp:
|
|
191
|
+
servers:
|
|
192
|
+
github:
|
|
193
|
+
transport: http_sse
|
|
194
|
+
url: https://mcp.github.com/v1
|
|
195
|
+
auth:
|
|
196
|
+
type: bearer
|
|
197
|
+
token_env: GITHUB_TOKEN
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
```yaml
|
|
201
|
+
# workflow.yaml (node using MCP tool)
|
|
202
|
+
nodes:
|
|
203
|
+
search_github:
|
|
204
|
+
type: mcp_tool
|
|
205
|
+
server: github
|
|
206
|
+
tool: search_code
|
|
207
|
+
input:
|
|
208
|
+
query: "{{ state.search_query }}"
|
|
209
|
+
output_schema: schemas.SearchResults
|
|
210
|
+
retry_policy: io_default
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### Delegating to an External Agent via A2A
|
|
214
|
+
|
|
215
|
+
```yaml
|
|
216
|
+
nodes:
|
|
217
|
+
code_review:
|
|
218
|
+
type: a2a_task
|
|
219
|
+
remote_agent: partner_reviewer # defined in agents.yaml
|
|
220
|
+
skill: security_review
|
|
221
|
+
input:
|
|
222
|
+
code: "{{ state.generated_code }}"
|
|
223
|
+
stream: true
|
|
224
|
+
timeout: 300s
|
|
225
|
+
on_input_required: human_review
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
---
|
|
229
|
+
|
|
230
|
+
## Architecture
|
|
231
|
+
|
|
232
|
+
```
|
|
233
|
+
┌──────────────────────────────────────────────────────────┐
|
|
234
|
+
│ Authoring Layer │
|
|
235
|
+
│ Python SDK | YAML | CLI │
|
|
236
|
+
├──────────────────────────────────────────────────────────┤
|
|
237
|
+
│ Compilation / Validation │
|
|
238
|
+
│ Graph IR | Schema | Policy lint │
|
|
239
|
+
├────────────────────────────┬─────────────────────────────┤
|
|
240
|
+
│ Rust Runtime Core │ Protocol Layer │
|
|
241
|
+
│ Scheduler | State SM │ MCP Client | MCP Server │
|
|
242
|
+
│ Event log | Snapshots │ A2A Client | A2A Server │
|
|
243
|
+
│ Workers | Timers │ Protocol Adapter Framework │
|
|
244
|
+
├────────────────────────────┴─────────────────────────────┤
|
|
245
|
+
│ Runtime Services │
|
|
246
|
+
│ Model Adapters | Tool Execution | Memory/Retrieval │
|
|
247
|
+
│ Policy Engine | Observability | Secret Management │
|
|
248
|
+
├──────────────────────────────────────────────────────────┤
|
|
249
|
+
│ Control Plane / APIs │
|
|
250
|
+
│ REST / gRPC | Agent Registry | Admin │
|
|
251
|
+
├──────────────────────────────────────────────────────────┤
|
|
252
|
+
│ Storage │
|
|
253
|
+
│ Postgres (production) | SQLite (local) │
|
|
254
|
+
└──────────────────────────────────────────────────────────┘
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
Read more: [Architecture Overview](docs/architecture/overview.md)
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
261
|
+
## Documentation
|
|
262
|
+
|
|
263
|
+
### Start here
|
|
264
|
+
|
|
265
|
+
| Guide | Description |
|
|
266
|
+
|-------|-------------|
|
|
267
|
+
| [Quickstart](docs/guides/quickstart.md) | Get a workflow running in 10 minutes |
|
|
268
|
+
| [Core Concepts](docs/guides/concepts.md) | Agents, workflows, nodes, state, durability |
|
|
269
|
+
| [Workflow Authoring](docs/guides/workflow-authoring.md) | YAML and Python authoring guide |
|
|
270
|
+
| [Python SDK](docs/guides/python-sdk.md) | Full SDK reference |
|
|
271
|
+
| [YAML Reference](docs/guides/yaml-reference.md) | Complete YAML spec |
|
|
272
|
+
|
|
273
|
+
### Connect to other systems
|
|
274
|
+
|
|
275
|
+
| Guide | Description |
|
|
276
|
+
|-------|-------------|
|
|
277
|
+
| [MCP Integration](docs/guides/mcp-guide.md) | Connect to MCP servers, expose tools |
|
|
278
|
+
| [A2A Integration](docs/guides/a2a-guide.md) | Delegate to and serve external agents |
|
|
279
|
+
| [Agent Model](docs/guides/agent-model-guide.md) | Agent Cards, lifecycle, autonomy levels |
|
|
280
|
+
| [Human-in-the-Loop](docs/guides/hitl.md) | Approval nodes, state editing, audit |
|
|
281
|
+
| [Observability](docs/guides/observability.md) | Traces, replay, cost attribution, OTel GenAI |
|
|
282
|
+
| [Deployment](docs/guides/deployment.md) | Production deployment guide |
|
|
283
|
+
|
|
284
|
+
### Advanced & enterprise
|
|
285
|
+
|
|
286
|
+
| Guide | Description |
|
|
287
|
+
|-------|-------------|
|
|
288
|
+
| [Security](docs/guides/security.md) | Auth, secrets, RBAC, OAuth delegated agent auth |
|
|
289
|
+
| [WASI Sandboxing](docs/guides/wasi-sandboxing.md) | Sandboxed tool execution via Wasmtime |
|
|
290
|
+
| [Eval Node](docs/guides/eval.md) | Evaluation as a workflow primitive |
|
|
291
|
+
| [ANP Discovery](docs/guides/anp.md) | Decentralized agent discovery via DID |
|
|
292
|
+
|
|
293
|
+
### Architecture deep-dives
|
|
294
|
+
|
|
295
|
+
| Document | Description |
|
|
296
|
+
|----------|-------------|
|
|
297
|
+
| [Architecture Overview](docs/architecture/overview.md) | Full system architecture |
|
|
298
|
+
| [Execution Model](docs/architecture/execution-model.md) | State machine, node types, IR |
|
|
299
|
+
| [State & Durability](docs/architecture/state-and-durability.md) | Event sourcing, snapshotting, recovery |
|
|
300
|
+
| [Agent Model](docs/architecture/agent-model.md) | Agent-native runtime design |
|
|
301
|
+
| [MCP Architecture](docs/architecture/mcp-integration.md) | MCP client/server internals |
|
|
302
|
+
| [A2A Architecture](docs/architecture/a2a-integration.md) | A2A protocol internals |
|
|
303
|
+
| [Protocol Adapters](docs/architecture/protocol-adapters.md) | Extensible protocol layer |
|
|
304
|
+
|
|
305
|
+
---
|
|
306
|
+
|
|
307
|
+
## Roadmap
|
|
308
|
+
|
|
309
|
+
| Phase | Status | Goal |
|
|
310
|
+
|-------|--------|------|
|
|
311
|
+
| 0 — Architecture & RFCs | In progress | Design docs, RFCs, scaffolding |
|
|
312
|
+
| 1 — Minimal Viable Runtime | Planned | Local durable execution, MCP client, agent cards |
|
|
313
|
+
| 2 — Production Core | Planned | Distributed workers, MCP server, full A2A |
|
|
314
|
+
| 3 — Developer Delight | Planned | Templates, eval harness, trace debugging |
|
|
315
|
+
| 4 — Enterprise | Planned | Policy engine, tenant isolation, federation security |
|
|
316
|
+
| 5 — Scale & Ecosystem | Planned | TypeScript SDK, hosted plane, agent marketplace |
|
|
317
|
+
|
|
318
|
+
Track milestone progress in [GitHub Issues](https://github.com/jamjet-labs/jamjet/issues) and the project board.
|
|
319
|
+
|
|
320
|
+
---
|
|
321
|
+
|
|
322
|
+
## Contributing
|
|
323
|
+
|
|
324
|
+
We welcome contributions of all kinds — bug reports, feature requests, documentation, and code.
|
|
325
|
+
|
|
326
|
+
- Read [CONTRIBUTING.md](CONTRIBUTING.md) to get started
|
|
327
|
+
- Check open issues for `good first issue` tags
|
|
328
|
+
- RFCs for major changes: see [docs/rfcs/](docs/rfcs/)
|
|
329
|
+
- Architecture decisions: see [docs/adr/](docs/adr/)
|
|
330
|
+
|
|
331
|
+
---
|
|
332
|
+
|
|
333
|
+
## Community
|
|
334
|
+
|
|
335
|
+
- **GitHub Discussions:** [github.com/jamjet-labs/jamjet/discussions](https://github.com/jamjet-labs/jamjet/discussions)
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
---
|
|
339
|
+
|
|
340
|
+
## License
|
|
341
|
+
|
|
342
|
+
Apache 2.0 — see [LICENSE](LICENSE).
|