Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions acp/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion acp/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ name = "iii-acp"
path = "src/main.rs"

[dependencies]
iii-sdk = "=0.11.3"
iii-sdk = "=0.13.0-next.1"
tokio = { version = "1", features = ["macros", "rt-multi-thread", "io-std", "io-util", "sync", "time", "signal"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
Expand Down
4 changes: 2 additions & 2 deletions console/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion console/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ path = "src/main.rs"
path = "src/lib.rs"

[dependencies]
iii-sdk = "=0.12.0-next.1"
iii-sdk = "=0.13.0-next.1"
tokio = { version = "1", features = ["rt-multi-thread", "macros", "sync", "signal", "net", "io-util", "time"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
Expand Down
1 change: 1 addition & 0 deletions console/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ async fn main() -> Result<()> {
os: std::env::consts::OS.to_string(),
pid: Some(std::process::id()),
telemetry: None,
..WorkerMetadata::default()
}),
..InitOptions::default()
},
Expand Down
6 changes: 3 additions & 3 deletions database/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion database/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ path = "src/main.rs"
path = "src/lib.rs"

[dependencies]
iii-sdk = "=0.12.0-next.1"
iii-sdk = "=0.13.0-next.1"
tokio = { version = "1", features = ["rt-multi-thread", "macros", "sync", "signal", "time"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
Expand Down
4 changes: 2 additions & 2 deletions iii-directory/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion iii-directory/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ name = "iii_directory"
path = "src/lib.rs"

[dependencies]
iii-sdk = "=0.11.6"
iii-sdk = "=0.13.0-next.1"
tokio = { version = "1", features = ["rt-multi-thread", "macros", "sync", "signal", "time", "fs", "process"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
Expand Down
62 changes: 54 additions & 8 deletions iii-directory/src/functions/directory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,63 @@

use std::sync::Arc;

use iii_sdk::{
FunctionInfo as SdkFunctionInfo, IIIError, RegisterFunction, TriggerInfo as SdkTriggerInfo,
TriggerRequest, TriggerTypeInfo, WorkerInfo, III,
};
use iii_sdk::{IIIError, RegisterFunction, TriggerRequest, III};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use serde_json::Value;

use crate::config::SkillsConfig;
use crate::how_to::{self, RelatedSkillRef};

/// Function information returned by `engine::functions::list`.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub(crate) struct SdkFunctionInfo {
pub function_id: String,
pub description: Option<String>,
pub request_format: Option<Value>,
pub response_format: Option<Value>,
pub metadata: Option<Value>,
}

/// Trigger information returned by `engine::triggers::list`.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub(crate) struct SdkTriggerInfo {
pub id: String,
pub trigger_type: String,
pub function_id: String,
pub config: Value,
pub metadata: Option<Value>,
}

/// Trigger type information returned by `engine::trigger-types::list`.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub(crate) struct TriggerTypeInfo {
pub id: String,
pub description: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub trigger_request_format: Option<Value>,
#[serde(skip_serializing_if = "Option::is_none")]
pub call_request_format: Option<Value>,
}

/// Worker information returned by `engine::workers::list`.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub(crate) struct WorkerInfo {
pub id: String,
pub name: Option<String>,
pub runtime: Option<String>,
pub version: Option<String>,
pub os: Option<String>,
pub ip_address: Option<String>,
pub status: String,
pub connected_at_ms: u64,
pub function_count: usize,
pub functions: Vec<String>,
pub active_invocations: usize,
#[serde(default)]
pub isolation: Option<String>,
}

// ---------- shared input/output shapes ----------

#[derive(Debug, Default, Deserialize, JsonSchema)]
Expand Down Expand Up @@ -788,7 +834,7 @@ pub async fn worker_info(iii: &III, input: WorkerInfoInput) -> Result<WorkerInfo
/// `description` is always `None` since the engine carries no
/// description for connected workers — the field exists for shape
/// parity with `registry::Worker`.
pub fn worker_envelope_from_sdk(w: WorkerInfo) -> Worker {
pub(crate) fn worker_envelope_from_sdk(w: WorkerInfo) -> Worker {
Worker {
name: w.name,
description: None,
Expand All @@ -808,7 +854,7 @@ pub fn worker_envelope_from_sdk(w: WorkerInfo) -> Worker {
/// Build a `function_id → worker_name` map from `WorkerInfo.functions[]`.
/// This is the canonical attribution; the namespace-segment fallback is
/// used only for unknown ids.
pub fn build_function_owner_map(
pub(crate) fn build_function_owner_map(
workers: &[WorkerInfo],
) -> std::collections::HashMap<String, String> {
let mut map = std::collections::HashMap::new();
Expand Down Expand Up @@ -852,7 +898,7 @@ fn truncate_chars(s: &str, max_chars: usize) -> String {
/// Internal: assemble `FunctionInfoOutput` from already-fetched lists.
/// The composite `registered-trigger-info` calls this so the bus isn't
/// hit twice for the same data.
pub fn function_info_core(
pub(crate) fn function_info_core(
functions: &[SdkFunctionInfo],
workers: &[WorkerInfo],
triggers: &[SdkTriggerInfo],
Expand Down Expand Up @@ -906,7 +952,7 @@ pub fn function_info_core(
}

/// Internal: assemble `TriggerInfoOutput` from already-fetched lists.
pub fn trigger_info_core(
pub(crate) fn trigger_info_core(
trigger_types: &[TriggerTypeInfo],
triggers: &[SdkTriggerInfo],
id: &str,
Expand Down
7 changes: 4 additions & 3 deletions iii-lsp/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion iii-lsp/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ name = "iii-lsp"
path = "src/main.rs"

[dependencies]
iii-sdk = "=0.11.3"
iii-sdk = "=0.13.0-next.1"
tower-lsp-server = "0.23"
tree-sitter = "0.24"
tree-sitter-typescript = "0.23"
Expand All @@ -18,6 +18,7 @@ tree-sitter-rust = "0.23"
tokio = { version = "1", features = ["rt-multi-thread", "macros", "io-std", "signal"] }
dashmap = "6"
serde_json = "1"
serde = { version = "1", features = ["derive"] }
clap = { version = "4", features = ["derive", "env"] }
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["fmt", "env-filter"] }
2 changes: 1 addition & 1 deletion iii-lsp/src/completions.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::analyzer::CompletionContext;
use crate::engine_client::EngineClient;
use iii_sdk::{FunctionInfo, TriggerTypeInfo};
use crate::engine_introspection::{FunctionInfo, TriggerTypeInfo};
use std::sync::Arc;
use tower_lsp_server::ls_types::*;

Expand Down
69 changes: 40 additions & 29 deletions iii-lsp/src/engine_client.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
use dashmap::{DashMap, DashSet};
use iii_sdk::{
register_worker, FunctionInfo, FunctionsAvailableGuard, IIIConnectionState, InitOptions,
TriggerInfo, TriggerTypeInfo, WorkerInfo, WorkerMetadata, III,
};
use iii_sdk::{register_worker, IIIConnectionState, InitOptions, WorkerMetadata, III};
use std::sync::{Arc, Mutex};

use crate::engine_introspection::{self, FunctionInfo, TriggerInfo, TriggerTypeInfo, WorkerInfo};

pub struct EngineClient {
iii: III,
pub functions: DashMap<String, FunctionInfo>,
Expand All @@ -15,7 +14,7 @@ pub struct EngineClient {
pub known_topics: DashSet<String>,
pub known_api_paths: DashSet<String>,
pub known_scopes: DashSet<String>,
guard: Mutex<Option<FunctionsAvailableGuard>>,
poll_task: Mutex<Option<tokio::task::JoinHandle<()>>>,
}

impl EngineClient {
Expand Down Expand Up @@ -45,39 +44,48 @@ impl EngineClient {
known_topics: DashSet::new(),
known_api_paths: DashSet::new(),
known_scopes: DashSet::new(),
guard: Mutex::new(None),
poll_task: Mutex::new(None),
})
}

pub async fn start(self: &Arc<Self>) {
self.seed_cache().await;

let weak = Arc::downgrade(self);
let guard = self.iii.on_functions_available(move |functions| {
let Some(client) = weak.upgrade() else {
return;
};
client.functions.clear();
for func in &functions {
client
.functions
.insert(func.function_id.clone(), func.clone());
}

let weak = Arc::downgrade(&client);
tokio::task::spawn(async move {
let handle = tokio::spawn(async move {
let mut interval = tokio::time::interval(std::time::Duration::from_secs(5));
loop {
interval.tick().await;
let Some(client) = weak.upgrade() else {
return;
break;
};
client.reseed_secondary_caches().await;
});
if !client.is_connected() {
continue;
}
if let Ok(functions) = engine_introspection::list_functions(&client.iii).await {
let changed = functions.len() != client.functions.len()
|| functions.iter().any(|f| {
client
.functions
.get(&f.function_id)
.is_none_or(|existing| existing.value() != f)
});
if changed {
client.functions.clear();
for func in functions {
client.functions.insert(func.function_id.clone(), func);
}
client.reseed_secondary_caches().await;
}
}
}
});

*self.guard.lock().unwrap() = Some(guard);
*self.poll_task.lock().unwrap() = Some(handle);
}

async fn seed_cache(&self) {
if let Ok(functions) = self.iii.list_functions().await {
if let Ok(functions) = engine_introspection::list_functions(&self.iii).await {
for func in functions {
self.functions.insert(func.function_id.clone(), func);
}
Expand All @@ -86,22 +94,23 @@ impl EngineClient {
}

async fn reseed_secondary_caches(&self) {
if let Ok(trigger_types) = self.iii.list_trigger_types(false).await {
if let Ok(trigger_types) = engine_introspection::list_trigger_types(&self.iii, false).await
{
self.trigger_types.clear();
for tt in trigger_types {
self.trigger_types.insert(tt.id.clone(), tt);
}
}

if let Ok(workers) = self.iii.list_workers().await {
if let Ok(workers) = engine_introspection::list_workers(&self.iii).await {
self.workers.clear();
for w in workers {
self.workers.insert(w.id.clone(), w);
}
}

// Extract known names from trigger configs
if let Ok(triggers) = self.iii.list_triggers(false).await {
if let Ok(triggers) = engine_introspection::list_triggers(&self.iii, false).await {
self.extract_known_values(&triggers);
}
}
Expand Down Expand Up @@ -180,8 +189,10 @@ impl EngineClient {
}

pub async fn shutdown(&self) {
if let Ok(mut guard) = self.guard.lock() {
*guard = None;
if let Ok(mut guard) = self.poll_task.lock() {
if let Some(handle) = guard.take() {
handle.abort();
}
}
self.iii.shutdown_async().await;
}
Expand Down
Loading
Loading