Skip to content

Commit ee098fa

Browse files
docs(community): showcase two external Opik projects + allow external proof_url (#56)
## What & why Showcases two external, community-built projects that use Opik, as **listed** entries in `community/`: - **[Building a Coding Agent from Scratch (course)](https://github.com/decodingai-magazine/building-a-coding-agent-from-scratch-course)** — Paul Iusztin / Decoding AI. Opik is used for tracing + evals (Lesson 7). - **[Observable Job Agent](https://github.com/jamwithai/observable-job-agent)** — Shirin Khosravi Jam / jamwithai. Observability-first CV→job-matching agent instrumented with Opik from run one. Both link out to the authors' own repos (`hosted: false`); no external code is vendored in. Since these are maintainer-added showcases (not author self-submissions), we don't hold the authors' Opik screenshots. So this PR also **relaxes the community proof rule**: an entry can now prove Opik usage with an http(s) `proof_url` in `meta.yaml` (pointing at the author's own trace screenshot / setup doc) as an alternative to a committed `opik-proof.png`. The committed-PNG path is unchanged for normal author submissions. ### Changes - `community/_ci/entry_rules.py` — `validate_proof` accepts a committed+referenced `opik-proof.png` **or** an http(s):// `proof_url`; signature unchanged, PNG path behavior preserved. - `community/_ci/tests/test_entry_rules.py` — new tests for the `proof_url` accept path, the non-http reject, the scheme-less (`httpfoo`) reject, and no-proof reject. Suite: 51 passing. - `community/templates/entry-template/meta.yaml` + `community/CONTRIBUTING.md` — document the optional `proof_url`. - Two new listed entries (`paul_iusztin_coding_agent_course/`, `jamwithai_observable_job_agent/`), each `meta.yaml` + `README.md`. - `community/README.md` — regenerated by `build_index.py` (two-row index). Each `proof_url` points at a real, public page in the author's repo showing Opik usage (a traces screenshot and an Opik setup/tracing doc, respectively) — no fabricated proof. ## Checklist <!-- The main-repo example contract (run.sh / litellm / uv / dry-run) does not apply to community entries — see community/CONTRIBUTING.md. --> - [x] Change confined to `community/` (its lighter-weight contract, not the root example contract) - [x] Folder names are `lowercase_with_underscores` and pass `community/_ci/check_entry.py` - [x] Both entries have all four required README sections and a valid `meta.yaml`; `author` is the owning GitHub org so `github.com/<author>` resolves - [x] Proof of Opik usage present (real external `proof_url` for each) - [x] `community/README.md` regenerated via `build_index.py` (`--check` clean) - [x] `python -m pytest -q` in `community/_ci` — 51 passing - [x] No credentials or `.env` files committed 🤖 Generated with [Claude Code](https://claude.com/claude-code)
2 parents ac423af + 55f454e commit ee098fa

9 files changed

Lines changed: 163 additions & 15 deletions

File tree

community/CONTRIBUTING.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,10 @@ are not executed by CI; a maintainer reviews (and, for hosted entries, runs)
88
them by hand.
99

1010
There is one thing we always require: **proof you actually logged with Opik**
11-
either Comet cloud or the self-hosted open-source platform.
11+
either Comet cloud or the self-hosted open-source platform. Provide it one of
12+
two ways: commit an `opik-proof.png` screenshot referenced from your `README.md`
13+
(the default for authors), or set an http(s) `proof_url` in `meta.yaml` pointing
14+
at your screenshot (used mainly when a maintainer showcases an external project).
1215

1316
## Two kinds of entry
1417

@@ -42,7 +45,8 @@ run your code. It checks:
4245
- `meta.yaml` has all required fields, at least one link, and a valid
4346
`opik_platform`.
4447
- `README.md` has all four sections filled in (no leftover `TODO`).
45-
- `opik-proof.png` exists and is referenced from your README.
48+
- Proof of Opik usage exists: either `opik-proof.png` (referenced from your
49+
README) or an http(s) `proof_url` in `meta.yaml`.
4650
- No `.env` file or hardcoded API keys are committed.
4751
- Hosted entries contain code that uses Opik.
4852
- The folder name is `lowercase_with_underscores`.

community/README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,7 @@ are hosted in-repo (see the Hosted column).
99

1010
To add your own, see [CONTRIBUTING.md](CONTRIBUTING.md).
1111

12-
_No community contributions yet — be the first!_
12+
| Project | Author | Description | Platform | Links | Hosted | Tags |
13+
|---|---|---|---|---|---|---|
14+
| [Building a Coding Agent from Scratch (course)](paul_iusztin_coding_agent_course/) | [@decodingai-magazine](https://github.com/decodingai-magazine) | An open-source course that builds a terminal coding agent from scratch, using Opik for tracing and evals. | cloud | [repo](https://github.com/decodingai-magazine/building-a-coding-agent-from-scratch-course) | | agent, course, coding-agent, evaluation, observability |
15+
| [Observable Job Agent](jamwithai_observable_job_agent/) | [@jamwithai](https://github.com/jamwithai) | An observability-first CV-to-job-matching agent, instrumented with Opik from run one. | cloud | [repo](https://github.com/jamwithai/observable-job-agent) | | agent, langgraph, observability, rag |

community/_ci/entry_rules.py

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -107,15 +107,27 @@ def validate_readme(entry: Path) -> list[str]:
107107

108108

109109
def validate_proof(entry: Path) -> list[str]:
110-
errors: list[str] = []
111-
if not (entry / "opik-proof.png").is_file():
112-
errors.append(f"{entry.name}: missing opik-proof.png (screenshot of your Opik traces)")
113-
return errors
114110
readme_path = entry / "README.md"
115-
text = readme_path.read_text(encoding="utf-8") if readme_path.is_file() else ""
116-
if "opik-proof.png" not in text:
117-
errors.append(f"{entry.name}: opik-proof.png must be referenced from README.md")
118-
return errors
111+
readme_text = readme_path.read_text(encoding="utf-8") if readme_path.is_file() else ""
112+
113+
png_path = entry / "opik-proof.png"
114+
if png_path.is_file():
115+
if "opik-proof.png" not in readme_text:
116+
return [f"{entry.name}: opik-proof.png must be referenced from README.md"]
117+
return []
118+
119+
# meta errors are reported by validate_meta; {} here falls through to the no-proof error
120+
data, _ = load_meta(entry)
121+
proof_url = data.get("proof_url")
122+
if _nonempty_str(proof_url) and str(proof_url).startswith(("http://", "https://")):
123+
return []
124+
125+
return [
126+
(
127+
f"{entry.name}: no proof of Opik usage — commit an opik-proof.png referenced "
128+
f"from README.md, or set an http(s) 'proof_url' in meta.yaml"
129+
)
130+
]
119131

120132

121133
_FOLDER_NAME_RE = re.compile(r"^[a-z0-9]+(?:_[a-z0-9]+)+$")
@@ -132,8 +144,10 @@ def validate_proof(entry: Path) -> list[str]:
132144
def validate_folder_name(entry: Path) -> list[str]:
133145
if not _FOLDER_NAME_RE.match(entry.name):
134146
return [
135-
f"{entry.name}: folder name must be lowercase '<author>_<project>' "
136-
f"(letters/digits/underscores, at least one underscore)"
147+
(
148+
f"{entry.name}: folder name must be lowercase '<author>_<project>' "
149+
f"(letters/digits/underscores, at least one underscore)"
150+
)
137151
]
138152
return []
139153

@@ -180,6 +194,8 @@ def validate_code_uses_opik(entry: Path) -> list[str]:
180194
if any(marker in text for marker in _OPIK_MARKERS):
181195
return []
182196
return [
183-
f"{entry.name}: hosted entry has no code that uses Opik "
184-
f"(expected one of: import opik, @opik.track, opik.Opik(, OPIK_)"
197+
(
198+
f"{entry.name}: hosted entry has no code that uses Opik "
199+
f"(expected one of: import opik, @opik.track, opik.Opik(, OPIK_)"
200+
)
185201
]

community/_ci/tests/test_entry_rules.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,3 +212,42 @@ def test_non_ascii_readme_and_meta_are_read_as_utf8(tmp_path: Path):
212212
)
213213
assert validate_readme(entry) == []
214214
assert validate_meta(entry) == []
215+
216+
217+
def test_proof_url_without_png_passes(tmp_path: Path):
218+
readme = (
219+
"# T\n\n## What I built\nA.\n\n## Problem it solves\nB.\n\n"
220+
"## What I learned\nC.\n\n## How I used Opik\n"
221+
"See the author's traces: https://example.com/opik.png\n"
222+
)
223+
entry = write_entry(
224+
tmp_path,
225+
readme=readme,
226+
include_png=False,
227+
meta={"proof_url": "https://example.com/opik.png"},
228+
)
229+
assert validate_proof(entry) == []
230+
231+
232+
def test_non_http_proof_url_without_png_is_error(tmp_path: Path):
233+
entry = write_entry(
234+
tmp_path,
235+
include_png=False,
236+
meta={"proof_url": "see my repo"},
237+
)
238+
assert any("proof" in e.lower() for e in validate_proof(entry))
239+
240+
241+
def test_schemeless_http_proof_url_without_png_is_error(tmp_path: Path):
242+
entry = write_entry(
243+
tmp_path,
244+
include_png=False,
245+
meta={"proof_url": "httpfoo-not-a-url"},
246+
)
247+
assert any("proof" in e.lower() for e in validate_proof(entry))
248+
249+
250+
def test_no_png_and_no_proof_url_is_error(tmp_path: Path):
251+
entry = write_entry(tmp_path, include_png=False)
252+
errors = validate_proof(entry)
253+
assert any("opik-proof.png" in e or "proof_url" in e for e in errors)
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Observable Job Agent
2+
3+
A community showcase of [Observable Job Agent](https://github.com/jamwithai/observable-job-agent),
4+
an open-source project by Shirin Khosravi Jam (jamwithai). We link to it here to
5+
spotlight how the community uses Opik — the code lives in the author's repo.
6+
7+
## What I built
8+
An MIT-licensed AI job-matching agent you run locally: upload a CV (PDF) and it
9+
produces a typed profile, searches real job listings across multiple sources, and
10+
ranks each posting with a 0–100 fit score plus an explanation of matches and gaps.
11+
It is built on LangGraph (agent graph + a bounded reformulation loop) with a Gradio
12+
three-step wizard, and it's Part 1 ("Build") of a "Build → Evaluate → Self-Improve"
13+
series.
14+
15+
## Problem it solves
16+
Job seekers waste hours manually judging whether a posting fits their background.
17+
This agent turns that into a structured, explainable ranking — and does it in a way
18+
whose cost, latency, and quality are measurable, so the agent can later be evaluated
19+
and improved rather than trusted blindly.
20+
21+
## What I learned
22+
The project's thesis is that observability comes first: the agent is instrumented
23+
*before* it is made good, so cost, latency, and quality are measurable from run one.
24+
That ordering makes Opik a design tool, not an afterthought — the span tree and
25+
agent graph reveal how each node behaves as the graph evolves.
26+
27+
## How I used Opik
28+
Opik (Comet) provides a span tree per LangGraph node, an auto-drawn agent graph, and
29+
per-run cost tracking; each run attaches the uploaded CV plus metadata (git SHA,
30+
model, job counts) and tags, and prompts are registered and versioned in Opik's
31+
prompt library. The Gradio run footer surfaces cost, latency, and a trace link. See
32+
the author's Opik setup and tracing guide:
33+
https://github.com/jamwithai/observable-job-agent/blob/main/docs/opik_setup.md
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
title: Observable Job Agent
2+
description: An observability-first CV-to-job-matching agent, instrumented with Opik from run one.
3+
author: jamwithai
4+
links:
5+
repo: https://github.com/jamwithai/observable-job-agent
6+
opik_platform: cloud
7+
proof_url: https://github.com/jamwithai/observable-job-agent/blob/main/docs/opik_setup.md
8+
tags: [agent, langgraph, observability, rag]
9+
hosted: false
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Building a Coding Agent from Scratch (course)
2+
3+
A community showcase of [Building a Coding Agent from Scratch](https://github.com/decodingai-magazine/building-a-coding-agent-from-scratch-course),
4+
an open-source course by Paul Iusztin (Decoding AI). We link to it here to spotlight
5+
how the community uses Opik — the code lives in the author's repo.
6+
7+
## What I built
8+
A project-based, Apache-2.0 course that walks engineers from a ~20-line agent loop
9+
to cloud-deployed subagent swarms. Across eight lessons it builds "the harness"
10+
around a coding agent — permissions, sandboxes, context compaction, subagent
11+
fan-out, a durable runtime, and evals — on a Pydantic AI ReAct loop with
12+
file/bash/web/LSP tools and Docker/Modal sandboxes.
13+
14+
## Problem it solves
15+
Most agent tutorials stop at the model call. This course targets the harder,
16+
production-shaped problem: the engineering *around* the model that makes a coding
17+
agent safe, observable, and reliable — the part teams actually have to build.
18+
19+
## What I learned
20+
Opik is wired in as an `observability/` module so every session is traced, with
21+
secrets scrubbed before they reach a log. Lesson 7 ("Benchmarks, regression probes,
22+
and online evals") shows how tracing feeds an eval suite, making agent behavior
23+
measurable rather than anecdotal as the harness grows.
24+
25+
## How I used Opik
26+
Each agent session is traced end-to-end (Opik threads), and the course's eval suite
27+
runs benchmarks, regression probes, and online evals against those traces. Opik
28+
(Comet) is a course sponsor and runs on the free tier. See the author's Opik
29+
threads screenshot:
30+
https://github.com/decodingai-magazine/building-a-coding-agent-from-scratch-course/blob/main/assets/opik-threads.png
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
title: Building a Coding Agent from Scratch (course)
2+
description: An open-source course that builds a terminal coding agent from scratch, using Opik for tracing and evals.
3+
author: decodingai-magazine
4+
links:
5+
repo: https://github.com/decodingai-magazine/building-a-coding-agent-from-scratch-course
6+
opik_platform: cloud
7+
proof_url: https://github.com/decodingai-magazine/building-a-coding-agent-from-scratch-course/blob/main/assets/opik-threads.png
8+
tags: [agent, course, coding-agent, evaluation, observability]
9+
hosted: false

community/templates/entry-template/meta.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ author: your-github-handle
55
links:
66
repo: https://github.com/your-handle/your-project # at least one http(s) link required
77
# blog: https://... # optional extra links
8+
# proof_url: https://github.com/your-handle/your-project/blob/main/assets/opik.png
9+
# # optional: link to a screenshot of your
10+
# # Opik traces INSTEAD of committing
11+
# # opik-proof.png (used mainly when a
12+
# # maintainer showcases an external project)
813
opik_platform: cloud # cloud | self-hosted
914
tags: [agent, rag] # free-form; may be empty []
1015
hosted: false # leave false; a maintainer sets this true when promoting

0 commit comments

Comments
 (0)