Skip to content

Commit 5a022cd

Browse files
louis030195claude
andcommitted
fix: pass ORG_TOKEN as env var for KV HTTP backend
Extract ORG_TOKEN from workflow inputs and set as env var along with KV_URL so @mediar-ai/kv auto-configures to use the remote HTTP backend. This fixes the issue where workflows were using local file-based KV instead of the shared remote KV store, causing duplicate detection to fail across different execution contexts. - Extract ORG_TOKEN from inputs before they're consumed - Set ORG_TOKEN and KV_URL env vars when spawning workflow process - Add unit tests for ORG_TOKEN extraction 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 4fa1cd5 commit 5a022cd

File tree

1 file changed

+61
-0
lines changed

1 file changed

+61
-0
lines changed

crates/terminator-mcp-agent/src/workflow_typescript.rs

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,12 @@ impl TypeScriptWorkflow {
375375
// Ensure dependencies are installed and cached
376376
self.ensure_dependencies_in(&execution_dir).await?;
377377

378+
// Extract ORG_TOKEN from inputs for KV HTTP backend (before inputs is consumed)
379+
let org_token = inputs
380+
.get("ORG_TOKEN")
381+
.and_then(|v| v.as_str())
382+
.map(|s| s.to_string());
383+
378384
// Create execution script (using execution_dir for imports)
379385
let exec_script = self.create_execution_script(
380386
&execution_dir,
@@ -617,6 +623,14 @@ impl TypeScriptWorkflow {
617623
debug!("Set TERMINATOR_WORKFLOW_ID={} (folder name)", folder);
618624
}
619625

626+
// Set ORG_TOKEN and KV_URL for HTTP KV backend if token is provided
627+
// This allows workflows to use the remote KV store via @mediar-ai/kv
628+
if let Some(ref token) = org_token {
629+
cmd.env("ORG_TOKEN", token);
630+
cmd.env("KV_URL", "https://app.mediar.ai/api/kv");
631+
debug!("Set ORG_TOKEN and KV_URL for HTTP KV backend");
632+
}
633+
620634
let mut child = cmd.spawn().map_err(|e| {
621635
McpError::internal_error(
622636
format!("Failed to execute workflow: {e}"),
@@ -1578,4 +1592,51 @@ mod tests {
15781592
assert_eq!(parsed.level, LogLevel::Info); // Falls through to default
15791593
assert_eq!(parsed.message, "[error] lowercase prefix");
15801594
}
1595+
1596+
#[test]
1597+
fn test_org_token_extraction_from_inputs() {
1598+
// Test that ORG_TOKEN can be extracted from inputs JSON
1599+
let inputs_with_token = serde_json::json!({
1600+
"ORG_TOKEN": "test-token-123",
1601+
"other_input": "value"
1602+
});
1603+
1604+
let org_token = inputs_with_token
1605+
.get("ORG_TOKEN")
1606+
.and_then(|v| v.as_str())
1607+
.map(|s| s.to_string());
1608+
1609+
assert_eq!(org_token, Some("test-token-123".to_string()));
1610+
}
1611+
1612+
#[test]
1613+
fn test_org_token_extraction_missing() {
1614+
// Test that missing ORG_TOKEN returns None
1615+
let inputs_without_token = serde_json::json!({
1616+
"other_input": "value"
1617+
});
1618+
1619+
let org_token = inputs_without_token
1620+
.get("ORG_TOKEN")
1621+
.and_then(|v| v.as_str())
1622+
.map(|s| s.to_string());
1623+
1624+
assert_eq!(org_token, None);
1625+
}
1626+
1627+
#[test]
1628+
fn test_org_token_extraction_null() {
1629+
// Test that null ORG_TOKEN returns None
1630+
let inputs_null_token = serde_json::json!({
1631+
"ORG_TOKEN": null,
1632+
"other_input": "value"
1633+
});
1634+
1635+
let org_token = inputs_null_token
1636+
.get("ORG_TOKEN")
1637+
.and_then(|v| v.as_str())
1638+
.map(|s| s.to_string());
1639+
1640+
assert_eq!(org_token, None);
1641+
}
15811642
}

0 commit comments

Comments
 (0)