dialograph 0.3.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.
Files changed (31) hide show
  1. dialograph-0.3.0/PKG-INFO +173 -0
  2. dialograph-0.3.0/README.md +162 -0
  3. dialograph-0.3.0/pyproject.toml +32 -0
  4. dialograph-0.3.0/setup.cfg +4 -0
  5. dialograph-0.3.0/src/dialograph/__init__.py +4 -0
  6. dialograph-0.3.0/src/dialograph/agent/__init__.py +0 -0
  7. dialograph-0.3.0/src/dialograph/agent/agent.py +58 -0
  8. dialograph-0.3.0/src/dialograph/agent/policy.py +76 -0
  9. dialograph-0.3.0/src/dialograph/agent/prompts.py +0 -0
  10. dialograph-0.3.0/src/dialograph/core/__init__.py +7 -0
  11. dialograph-0.3.0/src/dialograph/core/draw.py +7 -0
  12. dialograph-0.3.0/src/dialograph/core/edge.py +232 -0
  13. dialograph-0.3.0/src/dialograph/core/graph.py +93 -0
  14. dialograph-0.3.0/src/dialograph/core/node.py +77 -0
  15. dialograph-0.3.0/src/dialograph/memory/__init__.py +0 -0
  16. dialograph-0.3.0/src/dialograph/memory/belief.py +13 -0
  17. dialograph-0.3.0/src/dialograph/memory/preference.py +20 -0
  18. dialograph-0.3.0/src/dialograph/memory/strategy.py +11 -0
  19. dialograph-0.3.0/src/dialograph/traversal/__init__.py +0 -0
  20. dialograph-0.3.0/src/dialograph/traversal/retrieve.py +24 -0
  21. dialograph-0.3.0/src/dialograph/traversal/score.py +21 -0
  22. dialograph-0.3.0/src/dialograph/utils/__init__.py +0 -0
  23. dialograph-0.3.0/src/dialograph/utils/export.py +4 -0
  24. dialograph-0.3.0/src/dialograph/utils/io.py +10 -0
  25. dialograph-0.3.0/src/dialograph.egg-info/PKG-INFO +173 -0
  26. dialograph-0.3.0/src/dialograph.egg-info/SOURCES.txt +29 -0
  27. dialograph-0.3.0/src/dialograph.egg-info/dependency_links.txt +1 -0
  28. dialograph-0.3.0/src/dialograph.egg-info/requires.txt +3 -0
  29. dialograph-0.3.0/src/dialograph.egg-info/top_level.txt +1 -0
  30. dialograph-0.3.0/tests/test_graph.py +334 -0
  31. dialograph-0.3.0/tests/test_node_state.py +69 -0
@@ -0,0 +1,173 @@
1
+ Metadata-Version: 2.4
2
+ Name: dialograph
3
+ Version: 0.3.0
4
+ Summary: Dialograph is a Python toolkit for building, evolving, and reasoning over temporal dialogue graphs for proactive conversational agents.
5
+ Author: author
6
+ Requires-Python: >=3.11
7
+ Description-Content-Type: text/markdown
8
+ Requires-Dist: networkx>=3.6.1
9
+ Requires-Dist: numpy>=2.4.0
10
+ Requires-Dist: pydantic>=2.12.5
11
+
12
+ # dialograph
13
+
14
+ **Dialograph** is a lightweight Python library for representing, evolving, and traversing dialogue memory as a temporal graph.
15
+ It is designed for **proactive dialogue agents**, where reasoning over user preferences, beliefs, and strategies matters more than raw generation.
16
+
17
+ At its core, Dialograph wraps a dynamic graph structure around typed dialogue memories and provides clean hooks for retrieval, scoring, and long-term evolution.
18
+
19
+ ---
20
+
21
+ ## Core Concepts
22
+
23
+ ### Nodes
24
+
25
+ Nodes represent dialogue memory units such as:
26
+
27
+ * user preferences
28
+ * beliefs / facts
29
+ * dialogue strategies
30
+
31
+ Each node carries a **state object** (e.g. `PreferenceState`, `BeliefState`) with confidence and temporal metadata.
32
+
33
+ ### Edges
34
+
35
+ Edges represent relations between memory units:
36
+
37
+ * semantic relations (supports, contradicts, elicits)
38
+ * dialogue flow dependencies
39
+ * strategy activation paths
40
+
41
+ Edges are directional, weighted, and time-aware.
42
+
43
+ ### Time
44
+
45
+ Dialograph maintains an internal time counter that allows:
46
+
47
+ * decay of confidence
48
+ * forgetting
49
+ * recency-based retrieval
50
+
51
+ ---
52
+
53
+ ## Project Structure
54
+
55
+ ```text
56
+ dialograph/
57
+ ├── core/ # graph primitives
58
+ │ ├── graph.py # Dialograph wrapper
59
+ │ ├── node.py # node state definitions
60
+ │ └── edge.py # edge state definitions
61
+
62
+ ├── memory/ # typed dialogue memory
63
+ │ ├── preference.py
64
+ │ ├── belief.py
65
+ │ └── strategy.py
66
+
67
+ ├── traversal/ # retrieval and scoring
68
+ │ ├── retrieve.py
69
+ │ └── score.py
70
+
71
+ ├── utils/ # persistence & visualization
72
+ │ ├── io.py
73
+ │ └── visualize.py
74
+ ```
75
+
76
+ ---
77
+
78
+ ## Installation
79
+
80
+ For development:
81
+ ```bash
82
+ git clone https://github.com/nabin2004/dialograph.git
83
+ ```
84
+
85
+ ```bash
86
+ cd dialograph
87
+ ```
88
+
89
+ ```bash
90
+ uv venv
91
+ ```
92
+ ```bash
93
+ source .venv/bin/activate
94
+ ```
95
+
96
+ ```bash
97
+ uv pip install -e .
98
+ ```
99
+
100
+ ---
101
+
102
+ ## Quick Example
103
+
104
+ ```python
105
+ from dialograph.core.graph import Dialograph
106
+ from dialograph.memory.preference import PreferenceState
107
+ from dialograph.core.edge import EdgeState
108
+
109
+ g = Dialograph()
110
+
111
+ g.add_node(
112
+ "pref_movie",
113
+ state=PreferenceState(
114
+ key="movie_genre",
115
+ value="sci-fi",
116
+ confidence=0.9,
117
+ )
118
+ )
119
+
120
+ g.add_node(
121
+ "belief_stress",
122
+ state=BeliefState(
123
+ proposition="user is stressed about exams",
124
+ confidence=0.7,
125
+ )
126
+ )
127
+
128
+ g.add_edge(
129
+ "belief_stress",
130
+ "pref_movie",
131
+ state=EdgeState(relation="influences")
132
+ )
133
+ ```
134
+
135
+ ---
136
+
137
+ ## Intended Use Cases
138
+
139
+ * Proactive dialogue systems
140
+ * Emotional support agents
141
+ * Preference elicitation
142
+ * Strategy planning and reuse
143
+ * Dialogue memory research
144
+
145
+ ---
146
+
147
+ ## Status
148
+
149
+ This project is **under active development**.
150
+ APIs may evolve, but core abstractions are expected to remain stable.
151
+
152
+ ---
153
+
154
+ ## Roadmap
155
+
156
+ * [ ] Path-based retrieval
157
+ * [ ] Forgetting thresholds
158
+ * [ ] Graph serialization
159
+ * [ ] 3D / interactive visualization
160
+ * [ ] LLM-facing retrieval API
161
+
162
+ ---
163
+
164
+ ## License
165
+
166
+ MIT License.
167
+
168
+ ---
169
+
170
+ ## Citation
171
+
172
+ If you use Dialograph in academic work, please cite the corresponding paper (coming soon).
173
+
@@ -0,0 +1,162 @@
1
+ # dialograph
2
+
3
+ **Dialograph** is a lightweight Python library for representing, evolving, and traversing dialogue memory as a temporal graph.
4
+ It is designed for **proactive dialogue agents**, where reasoning over user preferences, beliefs, and strategies matters more than raw generation.
5
+
6
+ At its core, Dialograph wraps a dynamic graph structure around typed dialogue memories and provides clean hooks for retrieval, scoring, and long-term evolution.
7
+
8
+ ---
9
+
10
+ ## Core Concepts
11
+
12
+ ### Nodes
13
+
14
+ Nodes represent dialogue memory units such as:
15
+
16
+ * user preferences
17
+ * beliefs / facts
18
+ * dialogue strategies
19
+
20
+ Each node carries a **state object** (e.g. `PreferenceState`, `BeliefState`) with confidence and temporal metadata.
21
+
22
+ ### Edges
23
+
24
+ Edges represent relations between memory units:
25
+
26
+ * semantic relations (supports, contradicts, elicits)
27
+ * dialogue flow dependencies
28
+ * strategy activation paths
29
+
30
+ Edges are directional, weighted, and time-aware.
31
+
32
+ ### Time
33
+
34
+ Dialograph maintains an internal time counter that allows:
35
+
36
+ * decay of confidence
37
+ * forgetting
38
+ * recency-based retrieval
39
+
40
+ ---
41
+
42
+ ## Project Structure
43
+
44
+ ```text
45
+ dialograph/
46
+ ├── core/ # graph primitives
47
+ │ ├── graph.py # Dialograph wrapper
48
+ │ ├── node.py # node state definitions
49
+ │ └── edge.py # edge state definitions
50
+
51
+ ├── memory/ # typed dialogue memory
52
+ │ ├── preference.py
53
+ │ ├── belief.py
54
+ │ └── strategy.py
55
+
56
+ ├── traversal/ # retrieval and scoring
57
+ │ ├── retrieve.py
58
+ │ └── score.py
59
+
60
+ ├── utils/ # persistence & visualization
61
+ │ ├── io.py
62
+ │ └── visualize.py
63
+ ```
64
+
65
+ ---
66
+
67
+ ## Installation
68
+
69
+ For development:
70
+ ```bash
71
+ git clone https://github.com/nabin2004/dialograph.git
72
+ ```
73
+
74
+ ```bash
75
+ cd dialograph
76
+ ```
77
+
78
+ ```bash
79
+ uv venv
80
+ ```
81
+ ```bash
82
+ source .venv/bin/activate
83
+ ```
84
+
85
+ ```bash
86
+ uv pip install -e .
87
+ ```
88
+
89
+ ---
90
+
91
+ ## Quick Example
92
+
93
+ ```python
94
+ from dialograph.core.graph import Dialograph
95
+ from dialograph.memory.preference import PreferenceState
96
+ from dialograph.core.edge import EdgeState
97
+
98
+ g = Dialograph()
99
+
100
+ g.add_node(
101
+ "pref_movie",
102
+ state=PreferenceState(
103
+ key="movie_genre",
104
+ value="sci-fi",
105
+ confidence=0.9,
106
+ )
107
+ )
108
+
109
+ g.add_node(
110
+ "belief_stress",
111
+ state=BeliefState(
112
+ proposition="user is stressed about exams",
113
+ confidence=0.7,
114
+ )
115
+ )
116
+
117
+ g.add_edge(
118
+ "belief_stress",
119
+ "pref_movie",
120
+ state=EdgeState(relation="influences")
121
+ )
122
+ ```
123
+
124
+ ---
125
+
126
+ ## Intended Use Cases
127
+
128
+ * Proactive dialogue systems
129
+ * Emotional support agents
130
+ * Preference elicitation
131
+ * Strategy planning and reuse
132
+ * Dialogue memory research
133
+
134
+ ---
135
+
136
+ ## Status
137
+
138
+ This project is **under active development**.
139
+ APIs may evolve, but core abstractions are expected to remain stable.
140
+
141
+ ---
142
+
143
+ ## Roadmap
144
+
145
+ * [ ] Path-based retrieval
146
+ * [ ] Forgetting thresholds
147
+ * [ ] Graph serialization
148
+ * [ ] 3D / interactive visualization
149
+ * [ ] LLM-facing retrieval API
150
+
151
+ ---
152
+
153
+ ## License
154
+
155
+ MIT License.
156
+
157
+ ---
158
+
159
+ ## Citation
160
+
161
+ If you use Dialograph in academic work, please cite the corresponding paper (coming soon).
162
+
@@ -0,0 +1,32 @@
1
+ [project]
2
+ name = "dialograph"
3
+ version = "0.3.0"
4
+ description = "Dialograph is a Python toolkit for building, evolving, and reasoning over temporal dialogue graphs for proactive conversational agents."
5
+ readme = "README.md"
6
+ requires-python = ">=3.11"
7
+ authors = [
8
+ { name = "author" }
9
+ ]
10
+ dependencies = [
11
+ "networkx>=3.6.1",
12
+ "numpy>=2.4.0",
13
+ "pydantic>=2.12.5",
14
+ ]
15
+
16
+ [tool.hatch.build.targets.wheel]
17
+ packages = ["src/dialograph"]
18
+
19
+ #[tool.uv.extra-build-dependencies]
20
+ cchardet = ["cython"]
21
+
22
+ [dependency-groups]
23
+ dev = [
24
+ "black>=25.12.0",
25
+ "mkdocs>=1.6.1",
26
+ "mkdocs-material>=9.7.1",
27
+ "mkdocstrings[python]>=1.0.0",
28
+ "mypy>=1.19.1",
29
+ "pre-commit>=4.5.1",
30
+ "pytest>=9.0.2",
31
+ "ruff>=0.14.10",
32
+ ]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,4 @@
1
+ from .core.node import Node
2
+ from .core.edge import Edge
3
+
4
+ __all__ = ["Node", "Edge"]
File without changes
@@ -0,0 +1,58 @@
1
+ from typing import Any
2
+
3
+ from langchain_openai import ChatOpenAI
4
+ from langchain_core.prompts import ChatPromptTemplate, SystemMessagePromptTemplate, HumanMessagePromptTemplate, AIMessagePromptTemplate
5
+
6
+ class Agent:
7
+ def __init__(self, args):
8
+ self.args = args
9
+ self.cost = 0
10
+
11
+ def next_action(self, conversation) -> str:
12
+ raise NotImplementedError("Subclasses must implement this method.")
13
+
14
+ def generate_prompt(self, prompt_template: dict[str, Any]) -> ChatPromptTemplate:
15
+ messages = []
16
+ messages.append(SystemMessagePromptTemplate.from_template(prompt_template["system"]))
17
+ if "assistant" in prompt_template:
18
+ messages.append(AIMessagePromptTemplate.from_template(prompt_template["assistant"]))
19
+ if "user" in prompt_template:
20
+ messages.append(HumanMessagePromptTemplate.from_template(prompt_template["user"]))
21
+ final_prompt_template = ChatPromptTemplate.from_messages(messages)
22
+ return final_prompt_template
23
+
24
+
25
+ class DialographAgent:
26
+ """
27
+ Main agent class: proactive, curriculum-aware dialogue.
28
+ Integrates graph memory + temporal dynamics + policy.
29
+ """
30
+ def __init__(self, args):
31
+ self.data_name = args.data_name
32
+ self.api_key = args.api_key
33
+ self.args = args
34
+ self.mode = args.mode
35
+ self.activate_top_k = args.activate_top_k
36
+ self.activated_memory_nodes = []
37
+ self.recontextualized_guidance = []
38
+
39
+ def next_action(self, conversation) -> str:
40
+ pass
41
+
42
+ def revision(self, conversation) -> str:
43
+ pass
44
+
45
+ def extract_from_failure(self, conversation) -> str:
46
+ pass
47
+
48
+ def extract_from_success(self, conversation) -> str:
49
+ pass
50
+
51
+ def retrieve_nodes(self, conversation) -> str:
52
+ pass
53
+
54
+ def reinterpretation(self, conversation) -> str:
55
+ pass
56
+
57
+ def save_nodes(self, conversation) -> str:
58
+ pass
@@ -0,0 +1,76 @@
1
+ from enum import Enum
2
+ from typing import Optional, Tuple
3
+ from ..core.node import TemporalNode, MasteryLevel
4
+
5
+
6
+ class PedagogicalAction(Enum):
7
+ """Actions the agent can take"""
8
+ INTRODUCE = "introduce" # First time showing concept
9
+ PRACTICE = "practice" # Reinforce existing concept
10
+ REVIEW = "review" # Remediate forgotten concept
11
+ TEST = "test" # Assess mastery
12
+ WAIT = "wait" # No action needed
13
+
14
+
15
+ class CurriculumPolicy:
16
+ """
17
+ Decides WHAT to teach and WHEN.
18
+ Core of proactive behavior.
19
+ """
20
+
21
+ def __init__(self, review_threshold: float = 0.4, mastery_threshold: float = 0.8):
22
+ self.review_threshold = review_threshold
23
+ self.mastery_threshold = mastery_threshold
24
+
25
+ def decide_next_action(
26
+ self,
27
+ knowledge_graph: dict[str, TemporalNode]
28
+ ) -> Tuple[PedagogicalAction, Optional[TemporalNode]]:
29
+ """
30
+ Proactive decision logic.
31
+ Returns: (action, target_node)
32
+ """
33
+
34
+ # Priority 1: Review forgotten concepts (urgent)
35
+ for node in knowledge_graph.values():
36
+ if node.mastery == MasteryLevel.NEEDS_REVIEW:
37
+ return PedagogicalAction.REVIEW, node
38
+
39
+ # Priority 2: Practice concepts being learned
40
+ practicing_nodes = [
41
+ n for n in knowledge_graph.values()
42
+ if n.mastery == MasteryLevel.PRACTICING
43
+ ]
44
+ if practicing_nodes:
45
+ # Focus on weakest concept
46
+ weakest = min(practicing_nodes, key=lambda n: n.confidence)
47
+ return PedagogicalAction.PRACTICE, weakest
48
+
49
+ # Priority 3: Introduce new concepts (if prerequisites met)
50
+ for node in knowledge_graph.values():
51
+ if node.mastery == MasteryLevel.NOT_SEEN:
52
+ if self._prerequisites_satisfied(node, knowledge_graph):
53
+ return PedagogicalAction.INTRODUCE, node
54
+
55
+ # Priority 4: Test mastered concepts periodically
56
+ mastered = [n for n in knowledge_graph.values()
57
+ if n.mastery == MasteryLevel.MASTERED]
58
+ if mastered and len(mastered) % 5 == 0: # Every 5 mastered concepts
59
+ return PedagogicalAction.TEST, mastered[0]
60
+
61
+ # Nothing to do
62
+ return PedagogicalAction.WAIT, None
63
+
64
+ def _prerequisites_satisfied(
65
+ self,
66
+ node: TemporalNode,
67
+ graph: dict[str, TemporalNode]
68
+ ) -> bool:
69
+ """Check if all prerequisites are mastered"""
70
+ for prereq_id in node.prerequisites:
71
+ prereq = graph.get(prereq_id)
72
+ if not prereq:
73
+ return False
74
+ if prereq.mastery not in [MasteryLevel.MASTERED, MasteryLevel.PRACTICING]:
75
+ return False
76
+ return True
File without changes
@@ -0,0 +1,7 @@
1
+ # dialograph/core/__init__.py
2
+
3
+ from .node import Node
4
+ from .edge import Edge
5
+ from .graph import Dialograph
6
+
7
+ __all__ = ["Node", "Edge", "Dialograph"]
@@ -0,0 +1,7 @@
1
+ from graphviz import Digraph
2
+
3
+ def trace(root):
4
+ pass
5
+
6
+ def draw_dot():
7
+ pass