coaiajs 0.4.0 → 0.4.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
CHANGED
|
@@ -138,6 +138,10 @@ npx coaia <command> # or: npm i -g coaiajs && coaia <command>
|
|
|
138
138
|
|
|
139
139
|
Migration references: [Langfuse v4](https://langfuse.com/docs/v4) · [versions and compatibility](https://langfuse.com/docs/compatibility) · [deprecated API mapping](https://langfuse.com/faq/all/deprecated-api-migration) · [custom ingestion migration](https://langfuse.com/integrations/native/opentelemetry/migration-to-v4) · [current OpenAPI reference](https://cloud.langfuse.com/generated/api/openapi.yml).
|
|
140
140
|
|
|
141
|
+
### Custom GPT observation actions
|
|
142
|
+
|
|
143
|
+
[`agents/custom_gpt/ceremony-observations.yml`](./agents/custom_gpt/ceremony-observations.yml) is a focused OpenAPI 3.1 action specification for creating a root observation and appending child observations to the same Langfuse trace through OTLP/HTTP JSON. It contains 20 core actions—below the 30-action limit—and omits media and destructive operations. Setup, authentication, ID/timestamp rules, and ready-to-paste GPT instructions are in [`ceremony-observations.instructions.md`](./agents/custom_gpt/ceremony-observations.instructions.md). The broader imported API surface remains available in [`ceremony.yml`](./agents/custom_gpt/ceremony.yml).
|
|
144
|
+
|
|
141
145
|
---
|
|
142
146
|
|
|
143
147
|
## 3. MCP Server
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
# Ceremony Observations GPT Action
|
|
2
|
+
|
|
3
|
+
Use `ceremony-observations.yml` when the GPT must create Langfuse traces and append nested observations. It is intentionally smaller and more explicit than `ceremony.yml` so GPT Actions can reliably construct OTLP/HTTP JSON.
|
|
4
|
+
|
|
5
|
+
## What this specification solves
|
|
6
|
+
|
|
7
|
+
Langfuse v4 does not provide mutable REST trace and observation creation endpoints. A trace is the group of immutable observations sharing one `traceId`. The supported direct-ingestion path is:
|
|
8
|
+
|
|
9
|
+
```text
|
|
10
|
+
POST /api/public/otel/v1/traces
|
|
11
|
+
Content-Type: application/json
|
|
12
|
+
Authorization: Basic <base64(public-key:secret-key)>
|
|
13
|
+
x-langfuse-ingestion-version: 4
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
The `observations_export` action exposes that endpoint with a constrained OTLP schema and examples. It supports both:
|
|
17
|
+
|
|
18
|
+
1. Creating a trace by sending a root span without `parentSpanId`.
|
|
19
|
+
2. Appending an observation by reusing the trace ID and setting `parentSpanId` to an existing observation/span ID.
|
|
20
|
+
|
|
21
|
+
The file has **20 actions**, below the stated 30-action limit. Scores remain in this specification because the complete focused surface still fits. Media and destructive delete actions are omitted.
|
|
22
|
+
|
|
23
|
+
## Configure the Custom GPT
|
|
24
|
+
|
|
25
|
+
1. Import `ceremony-observations.yml` as the GPT Action schema.
|
|
26
|
+
2. If the Langfuse project is not in the EU region, replace the server URL first:
|
|
27
|
+
- US: `https://us.cloud.langfuse.com`
|
|
28
|
+
- Japan: `https://jp.cloud.langfuse.com`
|
|
29
|
+
- HIPAA: `https://hipaa.cloud.langfuse.com`
|
|
30
|
+
- Self-hosted: the deployment's public base URL
|
|
31
|
+
3. In the Action authentication UI choose **API Key** with a custom header:
|
|
32
|
+
- Header name: `Authorization`
|
|
33
|
+
- Value: `Basic BASE64_VALUE`
|
|
34
|
+
- `BASE64_VALUE` is the base64 encoding of `LANGFUSE_PUBLIC_KEY:LANGFUSE_SECRET_KEY` without a trailing newline.
|
|
35
|
+
4. Never put either Langfuse key or the encoded Authorization value in GPT instructions, knowledge files, or conversation messages.
|
|
36
|
+
5. Keep Code Interpreter/Data Analysis enabled if available. Before an export, use it to generate IDs and current timestamps rather than inventing them:
|
|
37
|
+
|
|
38
|
+
```python
|
|
39
|
+
import secrets, time
|
|
40
|
+
trace_id = secrets.token_hex(16) # only for a new trace
|
|
41
|
+
span_id = secrets.token_hex(8) # fresh for every observation
|
|
42
|
+
start_ns = time.time_ns()
|
|
43
|
+
# perform/describe the observed work
|
|
44
|
+
end_ns = max(time.time_ns(), start_ns)
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
The ingestion operation also declares the required `x-langfuse-ingestion-version` action header with the only allowed value `4`. If a GPT Actions client omits this non-auth header, Langfuse documents that direct OTLP ingestion still works but may take up to ten minutes to appear in v4 reads. A proxy is required if the client cannot send the header and real-time visibility is mandatory.
|
|
48
|
+
|
|
49
|
+
## Recommended GPT instructions
|
|
50
|
+
|
|
51
|
+
Add the following behavior to the GPT's instructions:
|
|
52
|
+
|
|
53
|
+
```markdown
|
|
54
|
+
### Langfuse tracing
|
|
55
|
+
|
|
56
|
+
Use observations_export to record ceremony work.
|
|
57
|
+
|
|
58
|
+
When starting a new trace:
|
|
59
|
+
1. Generate a cryptographically random, non-zero, lowercase 32-hex traceId.
|
|
60
|
+
2. Generate a cryptographically random, non-zero, lowercase 16-hex root spanId.
|
|
61
|
+
3. Calculate current Unix epoch nanoseconds as a decimal string.
|
|
62
|
+
4. Export one complete root span without parentSpanId.
|
|
63
|
+
5. Preserve the returned/local traceId and root spanId for later steps.
|
|
64
|
+
|
|
65
|
+
When adding an observation:
|
|
66
|
+
1. Reuse the exact 32-hex traceId.
|
|
67
|
+
2. Generate a fresh non-zero 16-hex spanId. Never reuse a spanId.
|
|
68
|
+
3. Set parentSpanId to the exact 16-hex ID of its parent observation.
|
|
69
|
+
4. Export a complete observation with start and end epoch-nanosecond strings.
|
|
70
|
+
5. Repeat trace-level attributes on the child.
|
|
71
|
+
|
|
72
|
+
Every span must include langfuse.observation.type. Allowed values are span,
|
|
73
|
+
generation, or event. JSON input/output must be serialized into stringValue.
|
|
74
|
+
For generations, include langfuse.observation.model.name and, when known,
|
|
75
|
+
langfuse.observation.usage_details as a JSON string.
|
|
76
|
+
|
|
77
|
+
Treat exported spans as immutable. Do not retry with the same spanId to edit a
|
|
78
|
+
span. To record a correction or later result, append a new child event/span.
|
|
79
|
+
|
|
80
|
+
After exporting, call observations_list with the traceId and fields
|
|
81
|
+
core,basic,time,io,metadata,model,usage,trace_context to verify the hierarchy.
|
|
82
|
+
Use each returned observation id as the span/parent ID for later children.
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Minimal append example
|
|
86
|
+
|
|
87
|
+
The parent trace and root observation must already exist. Replace every example value with live values; do not copy IDs or timestamps literally.
|
|
88
|
+
|
|
89
|
+
```json
|
|
90
|
+
{
|
|
91
|
+
"resourceSpans": [
|
|
92
|
+
{
|
|
93
|
+
"resource": {
|
|
94
|
+
"attributes": [
|
|
95
|
+
{
|
|
96
|
+
"key": "service.name",
|
|
97
|
+
"value": { "stringValue": "custom-gpt-ceremony" }
|
|
98
|
+
}
|
|
99
|
+
]
|
|
100
|
+
},
|
|
101
|
+
"scopeSpans": [
|
|
102
|
+
{
|
|
103
|
+
"scope": {
|
|
104
|
+
"name": "custom-gpt-ceremony",
|
|
105
|
+
"version": "0.4.0"
|
|
106
|
+
},
|
|
107
|
+
"spans": [
|
|
108
|
+
{
|
|
109
|
+
"traceId": "REPLACE_WITH_32_HEX_TRACE_ID",
|
|
110
|
+
"spanId": "REPLACE_16_HEX",
|
|
111
|
+
"parentSpanId": "REPLACE_16_HEX",
|
|
112
|
+
"name": "ceremony-step",
|
|
113
|
+
"kind": 1,
|
|
114
|
+
"startTimeUnixNano": "REPLACE_WITH_EPOCH_NANOSECONDS",
|
|
115
|
+
"endTimeUnixNano": "REPLACE_WITH_EPOCH_NANOSECONDS",
|
|
116
|
+
"attributes": [
|
|
117
|
+
{
|
|
118
|
+
"key": "langfuse.observation.type",
|
|
119
|
+
"value": { "stringValue": "span" }
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
"key": "langfuse.trace.name",
|
|
123
|
+
"value": { "stringValue": "ceremony" }
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
"key": "langfuse.observation.input",
|
|
127
|
+
"value": { "stringValue": "{\"step\":\"input\"}" }
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
"key": "langfuse.observation.output",
|
|
131
|
+
"value": { "stringValue": "{\"status\":\"complete\"}" }
|
|
132
|
+
}
|
|
133
|
+
],
|
|
134
|
+
"status": { "code": 1 }
|
|
135
|
+
}
|
|
136
|
+
]
|
|
137
|
+
}
|
|
138
|
+
]
|
|
139
|
+
}
|
|
140
|
+
]
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## Included action groups
|
|
145
|
+
|
|
146
|
+
| Group | Actions |
|
|
147
|
+
|---|---:|
|
|
148
|
+
| Observations and trace ingestion | 2 |
|
|
149
|
+
| Projects | 1 |
|
|
150
|
+
| Prompts | 4 |
|
|
151
|
+
| Datasets and dataset items | 6 |
|
|
152
|
+
| Scores and score configurations | 5 |
|
|
153
|
+
| Comments | 2 |
|
|
154
|
+
| **Total** | **20** |
|
|
155
|
+
|
|
156
|
+
## Why there are not separate create-trace and append-observation actions
|
|
157
|
+
|
|
158
|
+
OpenAPI allows one operation for each HTTP method/path pair, and Langfuse uses the same OTLP endpoint for both behaviors. The `observations_export` action distinguishes them through span context:
|
|
159
|
+
|
|
160
|
+
- root: new `traceId`, new `spanId`, no `parentSpanId`
|
|
161
|
+
- child: existing `traceId`, new `spanId`, existing parent `spanId`
|
|
162
|
+
|
|
163
|
+
A friendlier pair of actions with bodies such as `{traceId, parentId, input, output}` would require a trusted proxy that transforms those requests into OTLP and adds the ingestion-version header. An OpenAPI document alone cannot change Langfuse's wire contract.
|
|
164
|
+
|
|
165
|
+
## Primary references
|
|
166
|
+
|
|
167
|
+
- Langfuse OpenTelemetry integration: https://langfuse.com/integrations/native/opentelemetry
|
|
168
|
+
- Langfuse observability data model: https://langfuse.com/docs/observability/data-model
|
|
169
|
+
- Langfuse current OpenAPI document: https://cloud.langfuse.com/generated/api/openapi.yml
|
|
170
|
+
- OTLP JSON encoding: https://opentelemetry.io/docs/specs/otlp/#json-protobuf-encoding
|
|
171
|
+
- OpenAI GPT Actions introduction: https://developers.openai.com/api/docs/actions/introduction
|
|
172
|
+
- OpenAI GPT Action authentication: https://developers.openai.com/api/docs/actions/authentication
|
|
173
|
+
- OpenAI GPT Actions getting started: https://developers.openai.com/api/docs/actions/getting-started
|