@susu-eng/gralkor 27.1.0 → 27.2.0
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 +36 -11
- package/dist/client.d.ts +3 -13
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +3 -2
- package/dist/client.js.map +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +7 -3
- package/dist/config.js.map +1 -1
- package/dist/distill.d.ts +21 -0
- package/dist/distill.d.ts.map +1 -0
- package/dist/distill.js +88 -0
- package/dist/distill.js.map +1 -0
- package/dist/hooks.d.ts +14 -5
- package/dist/hooks.d.ts.map +1 -1
- package/dist/hooks.js +80 -13
- package/dist/hooks.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -6
- package/dist/index.js.map +1 -1
- package/dist/llm-client.d.ts +14 -0
- package/dist/llm-client.d.ts.map +1 -0
- package/dist/llm-client.js +122 -0
- package/dist/llm-client.js.map +1 -0
- package/dist/native-indexer.d.ts +11 -7
- package/dist/native-indexer.d.ts.map +1 -1
- package/dist/native-indexer.js +17 -33
- package/dist/native-indexer.js.map +1 -1
- package/dist/register.d.ts +1 -1
- package/dist/register.d.ts.map +1 -1
- package/dist/register.js +6 -5
- package/dist/register.js.map +1 -1
- package/dist/tools.d.ts +29 -9
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +25 -11
- package/dist/tools.js.map +1 -1
- package/openclaw.plugin.json +1 -1
- package/package.json +3 -2
- package/server/main.py +2 -192
- package/server/wheels/falkordblite-0.9.0-py3-none-manylinux_2_36_aarch64.whl +0 -0
package/dist/tools.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,UAAU,EAAc,MAAM,aAAa,CAAC;AAChF,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE5D,eAAO,MAAM,0BAA0B,QAEkC,CAAC;AAE1E,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAQlD;AAED,wBAAgB,UAAU,CAAC,CAAC,EAAE,IAAI,GAAG,MAAM,CAO1C;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,MAAM,CAIjD;AAED,wBAAgB,UAAU,CAAC,CAAC,EAAE,UAAU,GAAG,MAAM,CAEhD;AAED,MAAM,WAAW,QAAQ;IACvB,UAAU,CAAC,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,UAAU,EAAc,MAAM,aAAa,CAAC;AAChF,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE5D,eAAO,MAAM,0BAA0B,QAEkC,CAAC;AAE1E,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAQlD;AAED,wBAAgB,UAAU,CAAC,CAAC,EAAE,IAAI,GAAG,MAAM,CAO1C;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,MAAM,CAIjD;AAED,wBAAgB,UAAU,CAAC,CAAC,EAAE,UAAU,GAAG,MAAM,CAEhD;AAED,MAAM,WAAW,QAAQ;IACvB,UAAU,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,MAAM,CAAC;IAC3C,WAAW,CAAC,EAAE,SAAS,CAAC;CACzB;AAED,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,aAAa,EACrB,IAAI,EAAE,QAAQ;;;;;;;;;;;;;;;;;;;;;yBA0BG,MAAM,QACb;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,GAC1E,OAAO,CAAC,MAAM,CAAC;EAwBrB;AAED,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,aAAa,EACrB,IAAI,EAAE,QAAQ;;;;;;;;;;;;;;;;yBAkBG,MAAM,QACb;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,GAC3C,OAAO,CAAC,MAAM,CAAC;EA8BrB;AAED,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,cAAc,EACtB,IAAI,GAAE;IAAE,WAAW,CAAC,EAAE,SAAS,CAAA;CAAO;;;;;;;eAYnB,OAAO,CAAC,MAAM,CAAC;EAUnC;AAED,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,cAAc,EACtB,IAAI,EAAE,QAAQ;;;;;;;;;;;;;yBAmBe,MAAM,QAAQ;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC;EAWrF"}
|
package/dist/tools.js
CHANGED
|
@@ -26,7 +26,7 @@ export function formatFacts(facts) {
|
|
|
26
26
|
export function formatNode(n) {
|
|
27
27
|
return `- ${n.name}: ${n.summary ?? "(no summary)"}`;
|
|
28
28
|
}
|
|
29
|
-
export function createMemoryStoreTool(client, config, opts
|
|
29
|
+
export function createMemoryStoreTool(client, config, opts) {
|
|
30
30
|
const { getGroupId, serverReady } = opts;
|
|
31
31
|
return {
|
|
32
32
|
name: "memory_add",
|
|
@@ -42,14 +42,18 @@ export function createMemoryStoreTool(client, config, opts = {}) {
|
|
|
42
42
|
type: "string",
|
|
43
43
|
description: "Optional description of where this information came from",
|
|
44
44
|
},
|
|
45
|
+
session_key: {
|
|
46
|
+
type: "string",
|
|
47
|
+
description: "Session key from the gralkor-memory context block. Pass this to store in the correct agent memory partition.",
|
|
48
|
+
},
|
|
45
49
|
},
|
|
46
|
-
required: ["content"],
|
|
50
|
+
required: ["content", "session_key"],
|
|
47
51
|
},
|
|
48
52
|
async execute(_toolCallId, args) {
|
|
49
53
|
if (serverReady && !serverReady.isReady()) {
|
|
50
54
|
throw new Error(`[gralkor] memory_add failed: server is not ready`);
|
|
51
55
|
}
|
|
52
|
-
const groupId = getGroupId
|
|
56
|
+
const groupId = getGroupId(args.session_key);
|
|
53
57
|
console.log(`[gralkor] memory_add storing — groupId:${groupId} bodySize:${args.content.length}`);
|
|
54
58
|
if (config.test) {
|
|
55
59
|
console.log(`[gralkor] [test] episode body:\n${args.content}`);
|
|
@@ -66,23 +70,27 @@ export function createMemoryStoreTool(client, config, opts = {}) {
|
|
|
66
70
|
},
|
|
67
71
|
};
|
|
68
72
|
}
|
|
69
|
-
export function createMemorySearchTool(client, config, opts
|
|
73
|
+
export function createMemorySearchTool(client, config, opts) {
|
|
70
74
|
const { getGroupId, serverReady } = opts;
|
|
71
75
|
return {
|
|
72
76
|
name: "memory_search",
|
|
73
|
-
description: "Search memory for relevant context. Use specific, focused queries.",
|
|
77
|
+
description: "Search memory for relevant context. Use specific, focused queries. Pass the session_key from the gralkor-memory context block.",
|
|
74
78
|
parameters: {
|
|
75
79
|
type: "object",
|
|
76
80
|
properties: {
|
|
77
81
|
query: { type: "string" },
|
|
82
|
+
session_key: {
|
|
83
|
+
type: "string",
|
|
84
|
+
description: "Session key from the gralkor-memory context block. Pass this to search the correct agent memory partition.",
|
|
85
|
+
},
|
|
78
86
|
},
|
|
79
|
-
required: ["query"],
|
|
87
|
+
required: ["query", "session_key"],
|
|
80
88
|
},
|
|
81
89
|
async execute(_toolCallId, args) {
|
|
82
90
|
if (serverReady && !serverReady.isReady()) {
|
|
83
91
|
throw new Error("[gralkor] memory_search failed: server is not ready");
|
|
84
92
|
}
|
|
85
|
-
const groupId = getGroupId
|
|
93
|
+
const groupId = getGroupId(args.session_key);
|
|
86
94
|
const maxFacts = config.search.maxResults;
|
|
87
95
|
const maxEntities = config.search.maxEntityResults;
|
|
88
96
|
const results = await client.search(args.query, [groupId], maxFacts, "slow");
|
|
@@ -126,7 +134,7 @@ export function createBuildIndicesTool(client, opts = {}) {
|
|
|
126
134
|
},
|
|
127
135
|
};
|
|
128
136
|
}
|
|
129
|
-
export function createBuildCommunitiesTool(client, opts
|
|
137
|
+
export function createBuildCommunitiesTool(client, opts) {
|
|
130
138
|
const { getGroupId, serverReady } = opts;
|
|
131
139
|
return {
|
|
132
140
|
name: "memory_build_communities",
|
|
@@ -135,13 +143,19 @@ export function createBuildCommunitiesTool(client, opts = {}) {
|
|
|
135
143
|
"Run periodically or after significant new information has been ingested.",
|
|
136
144
|
parameters: {
|
|
137
145
|
type: "object",
|
|
138
|
-
properties: {
|
|
146
|
+
properties: {
|
|
147
|
+
session_key: {
|
|
148
|
+
type: "string",
|
|
149
|
+
description: "Session key from the gralkor-memory context block.",
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
required: ["session_key"],
|
|
139
153
|
},
|
|
140
|
-
async execute() {
|
|
154
|
+
async execute(_toolCallId, args) {
|
|
141
155
|
if (serverReady && !serverReady.isReady()) {
|
|
142
156
|
throw new Error(`[gralkor] memory_build_communities failed: server is not ready`);
|
|
143
157
|
}
|
|
144
|
-
const groupId = getGroupId
|
|
158
|
+
const groupId = getGroupId(args.session_key);
|
|
145
159
|
console.log(`[gralkor] memory_build_communities starting — groupId:${groupId}`);
|
|
146
160
|
const result = await client.buildCommunities(groupId);
|
|
147
161
|
console.log(`[gralkor] memory_build_communities done — communities:${result.communities} edges:${result.edges}`);
|
package/dist/tools.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,MAAM,0BAA0B,GACrC,8EAA8E;IAC9E,uEAAuE,CAAC;AAE1E,MAAM,UAAU,eAAe,CAAC,EAAU;IACxC,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAChC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC1B,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,wBAAwB,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE;QACxD,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;QACtC,OAAO,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,KAAK,IAAI,CAAC,EAAE,CAAC;IACjE,CAAC,CAAC,CAAC;IACH,OAAO,CAAC,CAAC;AACX,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,CAAO;IAChC,MAAM,GAAG,GAAG,CAAC,EAAU,EAAE,EAAE,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC;IAChD,MAAM,SAAS,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IACxE,MAAM,OAAO,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,gBAAgB,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IACrE,MAAM,SAAS,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,mBAAmB,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9E,MAAM,SAAS,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IACxE,OAAO,KAAK,CAAC,CAAC,IAAI,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,SAAS,EAAE,CAAC;AACrE,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAa;IACvC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,uBAAuB,CAAC;IACvD,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/C,OAAO,WAAW,KAAK,EAAE,CAAC;AAC5B,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,CAAa;IACtC,OAAO,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,OAAO,IAAI,cAAc,EAAE,CAAC;AACvD,CAAC;AAOD,MAAM,UAAU,qBAAqB,CACnC,MAAsB,EACtB,MAAqB,EACrB,
|
|
1
|
+
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"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"}
|
package/openclaw.plugin.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@susu-eng/gralkor",
|
|
3
|
-
"version": "27.
|
|
3
|
+
"version": "27.2.0",
|
|
4
4
|
"description": "OpenClaw memory plugin powered by Graphiti knowledge graphs and FalkorDB",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -75,6 +75,7 @@
|
|
|
75
75
|
"docker:up": "pnpm run docker:build && docker compose up -d",
|
|
76
76
|
"docker:down": "docker compose down",
|
|
77
77
|
"docker:logs": "docker compose logs graphiti",
|
|
78
|
-
"publish:npm": "bash scripts/publish.sh"
|
|
78
|
+
"publish:npm": "bash scripts/publish.sh",
|
|
79
|
+
"publish:clawhub": "bash scripts/publish-clawhub.sh"
|
|
79
80
|
}
|
|
80
81
|
}
|
package/server/main.py
CHANGED
|
@@ -8,7 +8,6 @@ import os
|
|
|
8
8
|
import time
|
|
9
9
|
from contextlib import asynccontextmanager
|
|
10
10
|
from copy import deepcopy
|
|
11
|
-
from dataclasses import dataclass, field
|
|
12
11
|
from datetime import datetime, timezone
|
|
13
12
|
from typing import Any, Literal
|
|
14
13
|
|
|
@@ -339,46 +338,6 @@ class AddEpisodeRequest(BaseModel):
|
|
|
339
338
|
idempotency_key: str
|
|
340
339
|
|
|
341
340
|
|
|
342
|
-
class ContentBlock(BaseModel):
|
|
343
|
-
"""A content block within a conversation message.
|
|
344
|
-
|
|
345
|
-
Supported types:
|
|
346
|
-
- "text": Natural language content (user input or assistant response).
|
|
347
|
-
- "thinking": Internal reasoning trace from the assistant.
|
|
348
|
-
- "tool_use": Serialized tool call (tool name + input).
|
|
349
|
-
- "tool_result": Truncated tool output.
|
|
350
|
-
The server groups thinking, tool_use, and tool_result blocks for
|
|
351
|
-
behaviour distillation before ingestion.
|
|
352
|
-
"""
|
|
353
|
-
type: str
|
|
354
|
-
text: str
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
class ConversationMessage(BaseModel):
|
|
358
|
-
"""A single message in a conversation transcript.
|
|
359
|
-
|
|
360
|
-
role: "user" for human input, "assistant" for agent output.
|
|
361
|
-
content: Ordered list of content blocks. A message may contain
|
|
362
|
-
multiple blocks (e.g. thinking followed by text).
|
|
363
|
-
"""
|
|
364
|
-
role: str
|
|
365
|
-
content: list[ContentBlock]
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
class IngestMessagesRequest(BaseModel):
|
|
369
|
-
"""Ingest a structured conversation for knowledge graph extraction.
|
|
370
|
-
|
|
371
|
-
The server formats the transcript, distills thinking blocks into
|
|
372
|
-
behaviour summaries, and creates an episode in the knowledge graph.
|
|
373
|
-
"""
|
|
374
|
-
name: str
|
|
375
|
-
source_description: str
|
|
376
|
-
group_id: str
|
|
377
|
-
messages: list[ConversationMessage]
|
|
378
|
-
reference_time: str | None = None
|
|
379
|
-
idempotency_key: str
|
|
380
|
-
|
|
381
|
-
|
|
382
341
|
class SearchRequest(BaseModel):
|
|
383
342
|
query: str
|
|
384
343
|
group_ids: list[str]
|
|
@@ -430,116 +389,10 @@ def _serialize_episode(ep: EpisodicNode) -> dict[str, Any]:
|
|
|
430
389
|
}
|
|
431
390
|
|
|
432
391
|
|
|
433
|
-
# ──
|
|
434
|
-
|
|
435
|
-
logger = logging.getLogger(__name__)
|
|
436
|
-
|
|
437
|
-
_DISTILL_SYSTEM_PROMPT = (
|
|
438
|
-
"You are a distillery for agentic thought and action. Given an AI agent's internal "
|
|
439
|
-
"thinking and tool usage from a conversation turn, capture the reasoning and actions "
|
|
440
|
-
"the agent took and contextualise them within the dialog. Write one to three sentences "
|
|
441
|
-
"— no filler, maximum distillation. Focus on reasoning, decisions, actions taken "
|
|
442
|
-
"(including which tools were used and why), and outcomes. "
|
|
443
|
-
"IMPORTANT: When the agent retrieves information from memory (memory_search results, "
|
|
444
|
-
"knowledge graph facts, etc.), do NOT repeat or summarize the retrieved content. "
|
|
445
|
-
"Instead, note that memory was consulted and focus on what the agent concluded, "
|
|
446
|
-
"decided, or did as a result. The retrieved facts are already stored — re-stating "
|
|
447
|
-
"them creates redundancy. Capture the thinking, not the remembering. "
|
|
448
|
-
"Write in first person, past tense. Output only the distilled text, nothing else."
|
|
449
|
-
)
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
async def _distill_one(llm_client: Any, thinking: str) -> str:
|
|
453
|
-
"""Distill a single turn's behaviour (thinking + tool use) into a summary."""
|
|
454
|
-
from graphiti_core.prompts.models import Message
|
|
455
|
-
|
|
456
|
-
messages = [
|
|
457
|
-
Message(role="system", content=_DISTILL_SYSTEM_PROMPT),
|
|
458
|
-
Message(role="user", content=thinking),
|
|
459
|
-
]
|
|
460
|
-
result = await llm_client.generate_response(messages, max_tokens=300)
|
|
461
|
-
return result.get("content", "").strip()
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
async def _distill_thinking(llm_client: Any, thinking_blocks: list[str]) -> list[str]:
|
|
465
|
-
"""Distill behaviour blocks (thinking + tool use) into summaries, one per turn.
|
|
466
|
-
|
|
467
|
-
Returns a list parallel to thinking_blocks. Failed entries are empty strings.
|
|
468
|
-
"""
|
|
469
|
-
|
|
470
|
-
async def _safe_distill(thinking: str) -> str:
|
|
471
|
-
if not thinking.strip():
|
|
472
|
-
return ""
|
|
473
|
-
try:
|
|
474
|
-
return await _distill_one(llm_client, thinking)
|
|
475
|
-
except Exception as e:
|
|
476
|
-
logger.warning("Behaviour distillation failed: %s", e)
|
|
477
|
-
return ""
|
|
478
|
-
|
|
479
|
-
return list(await asyncio.gather(*[_safe_distill(t) for t in thinking_blocks]))
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
async def _format_transcript(
|
|
483
|
-
msgs: list[ConversationMessage],
|
|
484
|
-
llm_client: Any | None,
|
|
485
|
-
) -> str:
|
|
486
|
-
"""Format structured messages into a transcript, distilling behaviour into summaries.
|
|
487
|
-
|
|
488
|
-
Each turn is a user message followed by assistant responses until the next
|
|
489
|
-
user message. Behaviour blocks (thinking, tool_use, tool_result) are distilled
|
|
490
|
-
into a single (behaviour: ...) line injected before the turn's assistant text.
|
|
491
|
-
"""
|
|
492
|
-
|
|
493
|
-
@dataclass
|
|
494
|
-
class Turn:
|
|
495
|
-
user_lines: list[str] = field(default_factory=list)
|
|
496
|
-
behaviour: list[str] = field(default_factory=list)
|
|
497
|
-
assistant_lines: list[str] = field(default_factory=list)
|
|
498
|
-
|
|
499
|
-
# Parse messages into turns
|
|
500
|
-
turns: list[Turn] = [Turn()]
|
|
501
|
-
for msg in msgs:
|
|
502
|
-
if msg.role == "user":
|
|
503
|
-
turns.append(Turn())
|
|
504
|
-
for block in msg.content:
|
|
505
|
-
if block.type == "text":
|
|
506
|
-
turns[-1].user_lines.append(block.text)
|
|
507
|
-
elif msg.role == "assistant":
|
|
508
|
-
for block in msg.content:
|
|
509
|
-
if block.type in ("thinking", "tool_use", "tool_result"):
|
|
510
|
-
turns[-1].behaviour.append(block.text)
|
|
511
|
-
elif block.type == "text":
|
|
512
|
-
turns[-1].assistant_lines.append(block.text)
|
|
513
|
-
|
|
514
|
-
# Distill behaviour blocks (only for turns that have them)
|
|
515
|
-
to_distill = [(i, "\n---\n".join(t.behaviour)) for i, t in enumerate(turns) if t.behaviour]
|
|
516
|
-
summaries: dict[int, str] = {}
|
|
517
|
-
if to_distill and llm_client:
|
|
518
|
-
texts = [text for _, text in to_distill]
|
|
519
|
-
sizes = [len(text) for text in texts]
|
|
520
|
-
logger.info("[gralkor] behaviour distillation — groups:%d sizes:%s totalChars:%d", len(texts), sizes, sum(sizes))
|
|
521
|
-
logger.debug("[gralkor] behaviour pre-distill:\n%s", "\n===\n".join(texts))
|
|
522
|
-
results = await _distill_thinking(llm_client, texts)
|
|
523
|
-
for (i, _), result in zip(to_distill, results):
|
|
524
|
-
if result:
|
|
525
|
-
summaries[i] = result
|
|
526
|
-
logger.info("[gralkor] behaviour distilled — %d/%d succeeded", len(summaries), len(texts))
|
|
527
|
-
logger.debug("[gralkor] behaviour post-distill: %s", summaries)
|
|
528
|
-
|
|
529
|
-
# Format transcript
|
|
530
|
-
lines: list[str] = []
|
|
531
|
-
for i, turn in enumerate(turns):
|
|
532
|
-
for text in turn.user_lines:
|
|
533
|
-
lines.append(f"User: {text}")
|
|
534
|
-
if i in summaries:
|
|
535
|
-
lines.append(f"Assistant: (behaviour: {summaries[i]})")
|
|
536
|
-
for text in turn.assistant_lines:
|
|
537
|
-
lines.append(f"Assistant: {text}")
|
|
538
|
-
|
|
539
|
-
return "\n".join(lines)
|
|
392
|
+
# ── Endpoints ─────────────────────────────────────────────────
|
|
540
393
|
|
|
541
394
|
|
|
542
|
-
|
|
395
|
+
logger = logging.getLogger(__name__)
|
|
543
396
|
|
|
544
397
|
|
|
545
398
|
@app.get("/health")
|
|
@@ -610,49 +463,6 @@ async def add_episode(req: AddEpisodeRequest):
|
|
|
610
463
|
return serialized
|
|
611
464
|
|
|
612
465
|
|
|
613
|
-
@app.post("/ingest-messages")
|
|
614
|
-
async def ingest_messages(req: IngestMessagesRequest):
|
|
615
|
-
cached = _idempotency_check(req.idempotency_key)
|
|
616
|
-
if cached is not None:
|
|
617
|
-
logger.info("[gralkor] ingest-messages idempotent hit — key:%s uuid:%s",
|
|
618
|
-
req.idempotency_key, cached.get("uuid"))
|
|
619
|
-
return cached
|
|
620
|
-
|
|
621
|
-
logger.info("[gralkor] ingest-messages — group:%s messages:%d", req.group_id, len(req.messages))
|
|
622
|
-
ref_time = (
|
|
623
|
-
datetime.fromisoformat(req.reference_time)
|
|
624
|
-
if req.reference_time
|
|
625
|
-
else datetime.now(timezone.utc)
|
|
626
|
-
)
|
|
627
|
-
llm = graphiti.llm_client if graphiti else None
|
|
628
|
-
episode_body = await _format_transcript(req.messages, llm)
|
|
629
|
-
|
|
630
|
-
logger.info("[gralkor] episode body — chars:%d lines:%d", len(episode_body), episode_body.count('\n') + 1)
|
|
631
|
-
logger.debug("[gralkor] episode body:\n%s", episode_body)
|
|
632
|
-
|
|
633
|
-
t0 = time.monotonic()
|
|
634
|
-
result = await graphiti.add_episode(
|
|
635
|
-
name=req.name,
|
|
636
|
-
episode_body=episode_body,
|
|
637
|
-
source_description=req.source_description,
|
|
638
|
-
group_id=req.group_id,
|
|
639
|
-
reference_time=ref_time,
|
|
640
|
-
source=EpisodeType.message,
|
|
641
|
-
entity_types=ontology_entity_types,
|
|
642
|
-
edge_types=ontology_edge_types,
|
|
643
|
-
edge_type_map=ontology_edge_type_map,
|
|
644
|
-
excluded_entity_types=None,
|
|
645
|
-
)
|
|
646
|
-
duration_ms = (time.monotonic() - t0) * 1000
|
|
647
|
-
episode = result.episode
|
|
648
|
-
logger.info("[gralkor] episode added — uuid:%s duration:%.0fms", episode.uuid, duration_ms)
|
|
649
|
-
logger.debug("[gralkor] episode result: %s", _serialize_episode(episode))
|
|
650
|
-
serialized = _serialize_episode(episode)
|
|
651
|
-
_idempotency_store_result(req.idempotency_key, serialized)
|
|
652
|
-
return serialized
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
466
|
def _sanitize_query(query: str) -> str:
|
|
657
467
|
"""Strip backticks that cause RediSearch syntax errors.
|
|
658
468
|
|
|
Binary file
|