Nardial Dialog System
Project description
NarDialPy
NarDialPy is a Python package for building and running narrative-driven, structured dialog systems — designed for social robots and conversational agents.
It lets you author complete conversations declaratively in JSON, then drive them from Python using voice, NLU, LLM, and browser-based screen services. The package handles session flow, branching logic, topic tracking, personalization, and screen output so you can focus on what the robot says and how conversations unfold.
Table of Contents
- What is nardial?
- Prerequisites & Setup
- Providers & Initialization
- Defining Dialogs in JSON
- Demos / Creating a Session
- Development
What is nardial?
The nardial package provides the building blocks for authoring and executing multi-turn conversations:
| Component | Description |
|---|---|
| Dialog JSON | Conversations are written as structured JSON files. Each file holds one or more dialogs, each containing a sequence of moves that the robot performs. |
| Session Manager | Loads your dialog JSON, resolves a session agenda, and runs dialogs in order — checking dependencies and tracking state. |
| ConversationAgent | The runtime bridge to the hardware: it calls TTS, STT, LLM, and motion services on your chosen device. |
| Screen Provider | Optional browser-based display layer for transcripts, images, videos, HTML, buttons, and web input. |
| Dialog Logic | Checks eligibility rules (dependencies, variable requirements) before executing each dialog. |
Typical use case:
- A social robot (Pepper, NAO, desktop agent) runs a structured conversation with a child or adult participant.
- The conversation is broken into named dialog blocks (greeting, story, chitchat, goodbye) authored in JSON.
- Python code wires up the device, credentials, and agenda — the JSON drives the actual content and branching.
Additional community demos are in the SIC Applications repository.
Prerequisites & Setup
1. Python IDE
Recommended: PyCharm or VS Code
2. Python
- Version: 3.12
- Download: https://www.python.org/downloads/release/python-3120/
- ⚠️ Ensure Python is added to your system
PATH
3. In your project, create and activate your python virtual environment
# Windows
cd your_project_folder
python -m venv venv_myproject
venv_myproject\Scripts\activate
# macOS / Linux
cd your_project_folder
python -m venv venv_myproject
source venv_myproject/bin/activate
4. Install NarDial
Install the core package, then add extras for each service you intend to use:
pip install nardial
| Extra | Enables | Install command |
|---|---|---|
google-tts |
Google Cloud Text-to-Speech | pip install "nardial[google-tts]" |
elevenlabs |
ElevenLabs Text-to-Speech | pip install "nardial[elevenlabs]" |
dialogflow |
Google Dialogflow NLU | pip install "nardial[dialogflow]" |
openai |
OpenAI GPT | pip install "nardial[openai]" |
all |
All of the above | pip install "nardial[all]" |
For robot devices, install the matching SIC device extra directly:
pip install "social-interaction-cloud[alphamini]" # Alphamini
Pepper and NAO are included in the base SIC package.
5. Configure Credentials
- Create a
conffolder at the root of your project. - Create a Google cloud project (for Dialogflow and google-tts services) and save the generated keyfile to
conf/google/google_keyfile.json. Instructions here. - Create an OpenAI account, and generate an API key and save it to
conf/openai/.openai_envwith the following content:
OPENAI_API_KEY="your key"
⚠️ Never commit credential files to version control.
6. Start Required Services
Run these in separate terminals before starting any demo:
# Windows
conf/redis/redis-server.exe conf/redis/redis.conf
# macOS / Linux
redis-server conf/redis/redis.conf
run-dialogflow
run-google-tts
run-gpt
Providers & Initialization
NarDialPy is built around a set of provider protocols. Each protocol defines a role (device, TTS, NLU, LLM, vector store) and multiple concrete implementations are available. You pick one implementation per role, instantiate it, and pass everything into ConversationAgent or SessionManager.
Available Providers
| Role | Provider | Import path | Requires |
|---|---|---|---|
| Device | DesktopAdapter |
nardial.providers.device.desktop |
base |
PepperAdapter |
nardial.providers.device.pepper |
base | |
NaoAdapter |
nardial.providers.device.nao |
base | |
AlphaminiAdapter |
nardial.providers.device.alphamini |
social-interaction-cloud[alphamini] |
|
| TTS | GoogleTTSProvider |
nardial.providers.tts.google |
nardial[google-tts] |
ElevenLabsTTSProvider |
nardial.providers.tts.elevenlabs |
nardial[elevenlabs] |
|
NaoqiTTSProvider |
nardial.providers.tts.naoqi |
base (uses device's built-in TTS) | |
NullTTSProvider |
nardial.providers.tts.null |
base (prints to terminal) | |
| NLU | DialogflowNLUProvider |
nardial.providers.nlu.dialogflow |
nardial[dialogflow] |
WrittenKeywordNLUProvider |
nardial.providers.nlu.written_keyword |
base (keyboard input) | |
| LLM | OpenAIGPTProvider |
nardial.providers.llm.openai_gpt |
nardial[openai] |
EchoLLMProvider |
nardial.providers.llm.echo |
base (echoes user input) | |
| Screen | ScreenProvider / SICScreenAdapter / PepperTabletScreenAdapter |
nardial.providers.screen |
browser display via SIC webserver |
| Vector store | RedisVectorStoreProvider |
nardial.providers.vector_store.redis_store |
base + running Redis |
NullVectorStoreProvider |
nardial.providers.vector_store.null |
base |
Minimal setup (no external services)
Good for local development and testing — all I/O goes through the terminal:
import logging
from sic_framework.devices.desktop import Desktop
from nardial.providers.device.desktop import DesktopAdapter
from nardial.providers.tts.null import NullTTSProvider
from nardial.providers.nlu.written_keyword import WrittenKeywordNLUProvider
from nardial.conversation_agent import ConversationAgent
desktop = Desktop()
device = DesktopAdapter(desktop)
device.setup(logger=logging.getLogger())
agent = ConversationAgent(
device=device,
tts_provider=NullTTSProvider(),
nlu_provider=WrittenKeywordNLUProvider(),
)
Desktop with cloud services
import json, logging
from sic_framework.devices.desktop import Desktop
from sic_framework.services.dialogflow.dialogflow import DialogflowConf
from nardial.providers.device.desktop import DesktopAdapter
from nardial.providers.tts.google import GoogleTTSProvider, GoogleTTSConf
from nardial.providers.tts.cacher import TTSCacher
from nardial.providers.nlu.dialogflow import DialogflowNLUProvider
from nardial.providers.llm.openai_gpt import OpenAIGPTProvider
from nardial.conversation_agent import ConversationAgent
desktop = Desktop()
device = DesktopAdapter(desktop)
device.setup(logger=logging.getLogger())
tts = GoogleTTSProvider(
conf=GoogleTTSConf(speaking_rate=0.9, google_tts_voice_name="en-US-Neural2-F"),
device=device,
keyfile_path="conf/google/google_keyfile.json",
tts_cacher=TTSCacher(tts_cache_dir="tts_cache"),
)
nlu = DialogflowNLUProvider(
conf=DialogflowConf(keyfile_json=json.load(open("conf/google/google_keyfile.json"))),
mic=desktop.mic,
)
llm = OpenAIGPTProvider(api_key="<YOUR_OPENAI_KEY>")
agent = ConversationAgent(
device=device,
tts_provider=tts,
nlu_provider=nlu,
llm_provider=llm,
)
Pepper robot
Swap the device adapter and TTS provider — everything else stays the same:
import logging
from sic_framework.devices import Pepper
from nardial.providers.device.pepper import PepperAdapter
from nardial.providers.tts.naoqi import NaoqiTTSProvider
pepper = Pepper(ip="<PEPPER_IP>")
device = PepperAdapter(pepper)
device.setup(logger=logging.getLogger())
tts = NaoqiTTSProvider(device=device, language="en")
Then pass device and tts to ConversationAgent as above.
Using SessionManager
SessionManager wraps ConversationAgent and adds dialog loading, eligibility checking, and session state:
from nardial.session_manager import SessionManager
manager = SessionManager(
agent=agent,
dialog_file="dialogs/my_dialogs.json",
participant_id="user_42",
)
manager.run()
Defining Dialogs in JSON
All conversation content lives in a JSON file (or directory of JSON files). The file is a JSON array of dialog objects.
Dialog Structure
Every dialog has the following shared fields:
| Field | Type | Required | Description |
|---|---|---|---|
id |
string | ✅ | Unique identifier referenced in session_agenda and dependencies |
type |
string | ✅ | Dialog type: "functional", "chitchat", "narrative", or "llm_based" |
moves |
array | ✅ | Ordered list of move objects the robot will perform |
dependencies |
array of strings | Dialog IDs that must have been completed before this dialog may run | |
variable_dependencies |
array | Variables that must exist in the user model before this dialog may run |
Example:
{
"id": "greeting",
"type": "functional",
"functional_type": "greeting",
"moves": [
{ "type": "say", "text": "Hi! I am your robot assistant." }
]
}
Dialog Types
Optional Top-Level characters
Dialogs can define reusable character voices:
{
"characters": {
"narrator": {
"voice_settings": {
"voice_id": "KTPVrSVAEUSJRClDzBw7",
"language": "en"
}
}
}
}
charactersis optional.- Each key is a character name.
- Each value must contain a
voice_settingsobject. voice_settingsis validated at runtime against the active TTS provider.
1.functional
Utility dialogs for session management — greetings, farewells, and structural transitions.
| Extra field | Type | Required | Description |
|---|---|---|---|
functional_type |
string | ✅ | "greeting" or "farewell" |
{
"id": "welcome",
"type": "functional",
"functional_type": "greeting",
"moves": [
{ "type": "say", "text": "Hello! What is your name?" },
{
"type": "ask_open",
"text": "Please tell me your name.",
"set_variable": "first_name"
}
]
}
2. chitchat
Short, theme-based conversations on everyday topics. Chitchat dialogs can be seeded with topics of interest so the system selects contextually relevant ones.
| Extra field | Type | Required | Description |
|---|---|---|---|
theme |
string | ✅ | Broad category (e.g. "nature", "animals", "robots") |
topics |
array of strings | Specific keywords used to drive relevance matching |
{
"id": "favorite_animal",
"type": "chitchat",
"theme": "animals",
"topics": ["animals", "pets"],
"moves": [
{
"type": "ask_open",
"text": "What is your favorite animal?",
"set_variable": "favorite_animal",
"add_interest_from_answer": true
},
{ "type": "say", "text": "I like %favorite_animal% too!" }
]
}
3. narrative
Story-based dialogs that belong to a named thread and must be delivered in a specific order. Use position to sequence them and dependencies to enforce ordering.
| Extra field | Type | Required | Description |
|---|---|---|---|
thread |
string | ✅ | Story thread name (e.g. "dreams") — groups related narrative dialogs |
position |
integer | ✅ | Order within the thread (1, 2, 3, …) |
{
"id": "dream_intro",
"type": "narrative",
"thread": "dreams",
"position": 1,
"moves": [
{ "type": "say", "text": "Sometimes I make up stories when I'm turned off." },
{
"type": "ask_yesno",
"text": "Do you ever dream?",
"set_variable": "dreams_yesno",
"outcomes": { "yes": "dreams_yes" },
"default_outcome": "dreams_no"
},
{
"type": "branch",
"on": "outcome",
"cases": {
"dreams_yes": [
{ "type": "say", "text": "That's great! Dreams are fascinating." }
],
"dreams_no": [
{ "type": "say", "text": "No problem, I'll tell you about mine!" }
]
}
}
]
}
4. llm_based
A fully LLM-driven dialog where the robot and user engage in a free-form multi-turn exchange guided by a system prompt. No moves array is needed — the LLM generates all responses.
| Extra field | Type | Required | Description |
|---|---|---|---|
prompt |
string | ✅ | System prompt guiding the LLM's behavior |
max_turns |
integer | Maximum back-and-forth turns (default: 5) | |
speak_first |
boolean | If true (default), the robot speaks first; if false, it listens first |
|
duration |
number | Time limit in seconds for the whole exchange | |
quit_phrases |
array of strings | User utterances that end the exchange early | |
quit_signal |
string | Token the LLM can embed to signal it wants to end (default: "<<QUIT>>") |
|
rag_enabled |
boolean | Enable Retrieval-Augmented Generation (RAG). When true, the LLM retrieves context from a vector index before generating responses. Requires configuring a compatible RAG backend through social-interaction-cloud. |
|
index_name |
string | Required when rag_enabled is true |
Name of the RAG index to query |
{
"id": "free_chat",
"type": "llm_based",
"prompt": "You are a friendly robot. Chat warmly with the child about their day. Ask follow-up questions. End with <<QUIT>> when the topic is exhausted.",
"max_turns": 6,
"speak_first": true,
"quit_signal": "<<QUIT>>",
"quit_phrases": ["goodbye", "stop", "done"],
"moves": []
}
Move Types
Moves are the individual steps inside a dialog's moves array. The robot executes them in order.
say
Speaks a piece of text. Variable placeholders (%variable_name%) are replaced at runtime.
| Field | Type | Required | Description |
|---|---|---|---|
type |
string | ✅ | "say" |
text |
string | ✅ | Text to speak. Use %var% to insert stored variables. |
character |
string | Optional character name from top-level characters; if omitted, default provider voice settings are used. |
{ "type": "say", "text": "Nice to meet you, %first_name%!" }
ask_open
Asks a free-text question and listens for any spoken reply. The answer can be stored in a variable and used to drive branching.
| Field | Type | Required | Description |
|---|---|---|---|
type |
string | ✅ | "ask_open" |
text |
string | ✅ | The question to ask |
set_variable |
string | Stores the extracted answer in the user model under this name | |
outcomes |
object | Maps answer values to outcome labels. Use "*" as a wildcard for any non-empty answer. |
|
default_outcome |
string | Outcome label when no answer or no match is found | |
add_interest_from_answer |
boolean | If true, adds the answer to the user's topics of interest |
|
llm_followup |
string | System prompt for an LLM-generated follow-up sentence after the user replies |
{
"type": "ask_open",
"text": "What is your favorite color?",
"set_variable": "favorite_color",
"add_interest_from_answer": true
}
ask_yesno
Asks a yes/no question. The detected intent ("yes", "no", "dontknow") drives branching.
| Field | Type | Required | Description |
|---|---|---|---|
type |
string | ✅ | "ask_yesno" |
text |
string | ✅ | The yes/no question to ask |
set_variable |
string | Stores the answer in the user model | |
outcomes |
object | Maps "yes" / "no" / "dontknow" to outcome labels |
|
default_outcome |
string | Outcome label used as fallback | |
add_interest |
string | Topic added to interest list when the user answers "yes" |
|
llm_followup |
string | System prompt for an LLM-generated follow-up sentence |
{
"type": "ask_yesno",
"text": "Do you like dogs?",
"set_variable": "likes_dogs",
"add_interest": "dogs",
"outcomes": { "yes": "likes_dogs_yes" },
"default_outcome": "likes_dogs_no"
}
ask_options
Presents a multiple-choice question. The selected option drives branching and can be stored as a variable.
| Field | Type | Required | Description |
|---|---|---|---|
type |
string | ✅ | "ask_options" |
text |
string | ✅ | The question to ask |
options |
array of strings | ✅ | The choices presented to the user |
set_variable |
string | Stores the selected option in the user model | |
outcomes |
object | Maps option values to outcome labels | |
default_outcome |
string | Outcome label when nothing matches | |
add_interest_from_variable |
string | After storing, adds the named variable's value as a topic of interest | |
llm_followup |
string | System prompt for an LLM-generated follow-up sentence |
{
"type": "ask_options",
"text": "Which activity do you prefer — reading, walking, or cooking?",
"options": ["reading", "walking", "cooking"],
"set_variable": "preferred_activity",
"outcomes": {
"reading": "chose_reading",
"walking": "chose_walking",
"cooking": "chose_cooking"
},
"default_outcome": "chose_other"
}
ask_llm
Starts a multi-turn LLM-driven exchange within an otherwise scripted dialog. Useful for a single free-form segment inside a structured conversation.
| Field | Type | Required | Description |
|---|---|---|---|
type |
string | ✅ | "ask_llm" |
prompt |
string | ✅ | System prompt for the LLM |
max_turns |
integer | Maximum turns (default: 5) | |
set_variable |
string | Stores the user's last reply in the user model | |
quit_phrases |
array of strings | User phrases that end the exchange early | |
quit_signal |
string | Token the LLM emits to signal it wants to stop |
{
"type": "ask_llm",
"prompt": "Ask one follow-up question to help the user commit to their plan for today. Keep it short and friendly.",
"max_turns": 1,
"set_variable": "plan_commitment"
}
branch
Selects and executes a list of sub-moves based on the current outcome or the value of a user model variable.
| Field | Type | Required | Description |
|---|---|---|---|
type |
string | ✅ | "branch" |
on |
string | ✅ | "outcome" to branch on the last question's result, or a variable name to branch on its stored value |
cases |
object | ✅ | Maps condition values to arrays of sub-moves |
{
"type": "branch",
"on": "outcome",
"cases": {
"chose_reading": [
{ "type": "say", "text": "Reading is a wonderful way to relax." }
],
"chose_walking": [
{ "type": "say", "text": "A walk sounds refreshing!" }
]
}
}
Branching on a stored variable (e.g. to react to an answer from an earlier dialog):
{
"type": "branch",
"on": "energy_level",
"cases": {
"high": [{ "type": "say", "text": "Start with a longer session." }],
"low": [{ "type": "say", "text": "Begin with just 10 calm minutes." }]
}
}
play
Plays an audio file through the device's speakers.
| Field | Type | Required | Description |
|---|---|---|---|
type |
string | ✅ | "play" |
audio |
string | ✅ | Path to the audio file (.wav or .mp3) |
{ "type": "play", "audio": "audio/chime.wav" }
motion_sequence
Plays a predefined motion sequence on the robot (Pepper / NAO).
| Field | Type | Required | Description |
|---|---|---|---|
type |
string | ✅ | "motion_sequence" |
motion_sequence |
string | ✅ | Path or name of the motion sequence file |
{ "type": "motion_sequence", "motion_sequence": "motions/Stand/Emotions/Positive/Happy_1" }
animation
Triggers a named animation behavior on the robot.
| Field | Type | Required | Description |
|---|---|---|---|
type |
string | ✅ | "animation" |
animation_name |
string | ✅ | Name of the animation to play |
{ "type": "animation", "animation_name": "animations/Stand/Gestures/Enthusiastic_4" }
timed_wait
Pause execution for a fixed duration before proceeding to the next move. Useful to add natural pauses or give the user time to look at the screen.
| Field | Type | Required | Description |
|---|---|---|---|
type |
string | ✅ | "timed_wait" |
duration_seconds |
number | ✅ | Seconds to wait. (Alias: duration is also accepted.) |
{ "type": "timed_wait", "duration_seconds": 2.5 }
wait_for_web_input
Suspend dialog execution until a matching web input event arrives or until a timeout elapses. The web UI can present buttons or a short input and emit web_input events which this move listens for.
| Field | Type | Required | Description |
|---|---|---|---|
type |
string | ✅ | "wait_for_web_input" |
prompt |
string | Hint text shown in the web UI (not spoken) | |
options |
array of strings | Accepted value strings from the web event (if omitted, any value is accepted) |
|
timeout |
number | Seconds to wait before falling back (omit for indefinite wait) | |
outcomes |
object | Maps option value → outcome label for branching | |
default_outcome |
string | Outcome used on timeout or when no event matches |
{
"type": "wait_for_web_input",
"prompt": "Choose a sticker to show",
"options": ["smile","thumbs","surprised"],
"timeout": 15,
"outcomes": {"smile": "picked_smile"},
"default_outcome": "no_choice"
}
show_image
Display an image on the connected screen (browser / tablet). Accepts a local path relative to the static assets directory or a full URL.
| Field | Type | Required | Description |
|---|---|---|---|
type |
string | ✅ | "show_image" |
src |
string | ✅ | Path or URL to the image (aliases: image, path) |
{ "type": "show_image", "src": "assets/images/robot_pet.png" }
show_video
Display a video on the screen. Can accept a local file path or an embeddable URL (e.g. a YouTube embed link).
| Field | Type | Required | Description |
|---|---|---|---|
type |
string | ✅ | "show_video" |
src |
string | ✅ | Video file path or embeddable URL (aliases: video, path) |
{ "type": "show_video", "src": "https://www.youtube.com/embed/VIDEO_ID" }
show_iframe
Embed an external web page inside an iframe on the screen. Use this for interactive web content served from a trusted origin.
| Field | Type | Required | Description |
|---|---|---|---|
type |
string | ✅ | "show_iframe" |
url |
string | ✅ | URL to embed (aliases: src, iframe_url) |
{ "type": "show_iframe", "url": "https://example.com/mini-game" }
show_html
Render a raw HTML snippet directly into the display area. The frontend inserts this via innerHTML — treat content as trusted and avoid injecting untrusted user data.
| Field | Type | Required | Description |
|---|---|---|---|
type |
string | ✅ | "show_html" |
html |
string | ✅ | HTML snippet to render |
{ "type": "show_html", "html": "<div class=\"card\">Hi there!</div>" }
black_screen
Clear the display (show a blank/black screen). No parameters — the next display move will restore content.
| Field | Type | Required | Description |
|---|---|---|---|
type |
string | ✅ | "black_screen" |
{ "type": "black_screen" }
Key JSON Attributes
| Attribute | Where used | Description |
|---|
Demos / Creating a Session
All you need is a minimal Python script that wires up the device, loads the dialog JSON, and runs the session. You can follow the included demos to get started quickly.
Two ready-to-run demos are included in the examples/ directory:
- Demo 1 — General Conversation (
demo_general_conversation.py): A simple four-step conversation using a mix of narrative and functional dialogs - Demo 2 — Structured Conversation (
demo_structured_conversation.py): A more complete example that demonstrates all dialog types and move types, includingask_llm,play,motion_sequence, andanimation - Demo 3 — Screen Display (
demo_screen_provider.py): Shows the browser-based screen UI with transcripts, images, iframes, HTML snippets, buttons, and text input - Demo 4 — Pepper Tablet (
demo_pepper_tablet.py): Uses the same screen UI on Pepper's tablet through the SIC webserver
You can find additional demos in the SIC Applications repository
Development
Run tests from the repository root:
python -m pytest -q
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file nardial-0.3.1.tar.gz.
File metadata
- Download URL: nardial-0.3.1.tar.gz
- Upload date:
- Size: 109.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dd218e03d727c1a2cb004d0eaf4acddf6c7d25ca4830ff22694da5d31a8cd0cc
|
|
| MD5 |
69069f47b6c8f17160ccf1d3a47cc821
|
|
| BLAKE2b-256 |
0f9f2c8db429bb5fcf38c5030344b0f788817afb1595105b96fa4fd26d3fcf27
|
Provenance
The following attestation bundles were made for nardial-0.3.1.tar.gz:
Publisher:
publish.yml on Social-AI-VU/NarDialPy
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
nardial-0.3.1.tar.gz -
Subject digest:
dd218e03d727c1a2cb004d0eaf4acddf6c7d25ca4830ff22694da5d31a8cd0cc - Sigstore transparency entry: 1763746923
- Sigstore integration time:
-
Permalink:
Social-AI-VU/NarDialPy@0afca6e72eee32390c143cf7e57dac3db62c7533 -
Branch / Tag:
refs/tags/v0.3.1 - Owner: https://github.com/Social-AI-VU
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@0afca6e72eee32390c143cf7e57dac3db62c7533 -
Trigger Event:
release
-
Statement type:
File details
Details for the file nardial-0.3.1-py3-none-any.whl.
File metadata
- Download URL: nardial-0.3.1-py3-none-any.whl
- Upload date:
- Size: 108.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ab99d155e4d7314617c3924cdef7c0b471878070f7344d6b4296fae53a65e24c
|
|
| MD5 |
cfb912a5f402226eca9974ef30e1e96a
|
|
| BLAKE2b-256 |
9a6ee9591c806b591369f1ee5232effb99b117dc633565e21f7f180271dd305b
|
Provenance
The following attestation bundles were made for nardial-0.3.1-py3-none-any.whl:
Publisher:
publish.yml on Social-AI-VU/NarDialPy
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
nardial-0.3.1-py3-none-any.whl -
Subject digest:
ab99d155e4d7314617c3924cdef7c0b471878070f7344d6b4296fae53a65e24c - Sigstore transparency entry: 1763747789
- Sigstore integration time:
-
Permalink:
Social-AI-VU/NarDialPy@0afca6e72eee32390c143cf7e57dac3db62c7533 -
Branch / Tag:
refs/tags/v0.3.1 - Owner: https://github.com/Social-AI-VU
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@0afca6e72eee32390c143cf7e57dac3db62c7533 -
Trigger Event:
release
-
Statement type: