Skip to content

Commit 1614f4c

Browse files
committed
[Components] langfuse - new components
1 parent 9c03bce commit 1614f4c

File tree

12 files changed

+734
-13
lines changed

12 files changed

+734
-13
lines changed
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
import constants from "../../common/constants.mjs";
2+
import app from "../../langfuse.app.mjs";
3+
4+
export default {
5+
key: "langfuse-add-feedback",
6+
name: "Add Feedback",
7+
description: "Attach user feedback to an existing trace in Langfuse. [See the documentation](https://api.reference.langfuse.com/#tag/comments/POST/api/public/comments).",
8+
version: "0.0.1",
9+
type: "action",
10+
props: {
11+
app,
12+
projectId: {
13+
propDefinition: [
14+
app,
15+
"projectId",
16+
],
17+
},
18+
objectType: {
19+
propDefinition: [
20+
app,
21+
"objectType",
22+
],
23+
},
24+
objectId: {
25+
propDefinition: [
26+
app,
27+
"objectId",
28+
({ objectType }) => ({
29+
objectType,
30+
}),
31+
],
32+
},
33+
content: {
34+
type: "string",
35+
label: "Content",
36+
description: "The content of the comment. May include markdown. Currently limited to 3000 characters.",
37+
},
38+
},
39+
methods: {
40+
addFeedback(args = {}) {
41+
return this.app.post({
42+
path: "/comments",
43+
...args,
44+
});
45+
},
46+
async getObjectId() {
47+
const {
48+
app,
49+
objectType,
50+
objectId,
51+
} = this;
52+
if (objectType == constants.OBJECT_TYPE.PROMPT) {
53+
const prompt = await app.getPrompt({
54+
promptName: objectId,
55+
});
56+
return prompt?.id;
57+
}
58+
return objectId;
59+
},
60+
},
61+
async run({ $ }) {
62+
const {
63+
getObjectId,
64+
addFeedback,
65+
projectId,
66+
objectType,
67+
content,
68+
} = this;
69+
70+
const objectId = await getObjectId();
71+
72+
const response = await addFeedback({
73+
$,
74+
data: {
75+
projectId,
76+
objectType,
77+
objectId,
78+
content,
79+
},
80+
});
81+
82+
$.export("$summary", "Successfully added feedback.");
83+
return response;
84+
},
85+
};
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
import { v4 as uuid } from "uuid";
2+
import app from "../../langfuse.app.mjs";
3+
import constants from "../../common/constants.mjs";
4+
import utils from "../../common/utils.mjs";
5+
6+
export default {
7+
key: "langfuse-log-trace",
8+
name: "Log Trace",
9+
description: "Log a new trace in LangFuse with details. [See the documentation](https://api.reference.langfuse.com/#tag/ingestion/POST/api/public/ingestion).",
10+
version: "0.0.1",
11+
type: "action",
12+
props: {
13+
app,
14+
name: {
15+
type: "string",
16+
label: "Name",
17+
description: "The name of the trace",
18+
},
19+
input: {
20+
type: "string",
21+
label: "Input",
22+
description: "The input of the trace",
23+
},
24+
output: {
25+
type: "string",
26+
label: "Output",
27+
description: "The output of the trace",
28+
},
29+
userId: {
30+
type: "string",
31+
label: "User ID",
32+
description: "The ID of the user",
33+
optional: true,
34+
},
35+
sessionId: {
36+
label: "Session ID",
37+
description: "The ID of the session",
38+
optional: true,
39+
propDefinition: [
40+
app,
41+
"objectId",
42+
() => ({
43+
objectType: constants.OBJECT_TYPE.SESSION,
44+
}),
45+
],
46+
},
47+
release: {
48+
type: "string",
49+
label: "Release",
50+
description: "The release of the trace",
51+
optional: true,
52+
},
53+
version: {
54+
type: "string",
55+
label: "Version",
56+
description: "The version of the trace",
57+
optional: true,
58+
},
59+
metadata: {
60+
type: "string",
61+
label: "Metadata",
62+
description: "The metadata of the trace",
63+
optional: true,
64+
},
65+
tags: {
66+
type: "string[]",
67+
label: "Tags",
68+
description: "The tags of the trace",
69+
optional: true,
70+
},
71+
},
72+
methods: {
73+
batchIngestion(args = {}) {
74+
return this.app.post({
75+
path: "/ingestion",
76+
...args,
77+
});
78+
},
79+
},
80+
async run({ $ }) {
81+
const {
82+
batchIngestion,
83+
name,
84+
userId,
85+
input,
86+
output,
87+
sessionId,
88+
release,
89+
version,
90+
metadata,
91+
tags,
92+
} = this;
93+
94+
const timestamp = new Date().toISOString();
95+
const id = uuid();
96+
97+
const response = await batchIngestion({
98+
$,
99+
data: {
100+
batch: [
101+
{
102+
id,
103+
timestamp,
104+
type: constants.INGESTION_TYPE.TRACE_CREATE,
105+
body: {
106+
id,
107+
timestamp,
108+
name,
109+
userId,
110+
input: utils.parseJson(input),
111+
output: utils.parseJson(output),
112+
sessionId,
113+
release,
114+
version,
115+
metadata: utils.parseJson(metadata),
116+
tags,
117+
public: true,
118+
},
119+
},
120+
],
121+
},
122+
});
123+
$.export("$summary", "Successfully logged a new trace");
124+
return response;
125+
},
126+
};
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
const REGION_PLACEHOLDER = "{region}";
2+
const BASE_URL = "https://{region}.langfuse.com";
3+
const VERSION_PATH = "/api/public";
4+
5+
const INGESTION_TYPE = {
6+
TRACE_CREATE: "trace-create",
7+
SCORE_CREATE: "score-create",
8+
SPAN_CREATE: "span-create",
9+
SPAN_UPDATE: "span-update",
10+
GENERATION_CREATE: "generation-create",
11+
GENERATION_UPDATE: "generation-update",
12+
EVENT_CREATE: "event-create",
13+
SDK_LOG: "sdk-log",
14+
OBSERVATION_CREATE: "observation-create",
15+
OBSERVATION_UPDATE: "observation-update",
16+
};
17+
18+
const LAST_DATE_AT = "lastDateAt";
19+
const IS_FIRST_RUN = "isFirstRun";
20+
const DEFAULT_LIMIT = 100;
21+
const DEFAULT_MAX = 1000;
22+
23+
const OBJECT_TYPE = {
24+
TRACE: "TRACE",
25+
OBSERVATION: "OBSERVATION",
26+
SESSION: "SESSION",
27+
PROMPT: "PROMPT",
28+
};
29+
30+
export default {
31+
REGION_PLACEHOLDER,
32+
BASE_URL,
33+
VERSION_PATH,
34+
INGESTION_TYPE,
35+
LAST_DATE_AT,
36+
IS_FIRST_RUN,
37+
DEFAULT_LIMIT,
38+
DEFAULT_MAX,
39+
OBJECT_TYPE,
40+
};
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
async function iterate(iterations) {
2+
const items = [];
3+
for await (const item of iterations) {
4+
items.push(item);
5+
}
6+
return items;
7+
}
8+
9+
function getNestedProperty(obj, propertyString) {
10+
const properties = propertyString.split(".");
11+
return properties.reduce((prev, curr) => prev?.[curr], obj);
12+
}
13+
14+
const parseJson = (input) => {
15+
const parse = (value) => {
16+
if (typeof(value) === "string") {
17+
try {
18+
return parseJson(JSON.parse(value));
19+
} catch (e) {
20+
return value;
21+
}
22+
} else if (typeof(value) === "object" && value !== null) {
23+
return Object.entries(value)
24+
.reduce((acc, [
25+
key,
26+
val,
27+
]) => Object.assign(acc, {
28+
[key]: parse(val),
29+
}), {});
30+
}
31+
return value;
32+
};
33+
34+
return parse(input);
35+
};
36+
37+
export default {
38+
iterate,
39+
getNestedProperty,
40+
parseJson,
41+
};

0 commit comments

Comments
 (0)