expo-ai-kit 0.1.8 → 0.1.10

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.
@@ -1,10 +1,9 @@
1
1
  {
2
- "name": "ExpoAiKit",
3
- "platforms": ["ios", "android", "web"],
4
- "ios": {
2
+ "platforms": ["apple", "android", "web"],
3
+ "apple": {
5
4
  "modules": ["ExpoAiKitModule"]
6
5
  },
7
6
  "android": {
8
7
  "modules": ["expo.modules.aikit.ExpoAiKitModule"]
9
8
  }
10
- }
9
+ }
@@ -7,7 +7,7 @@ public class ExpoAiKitModule: Module {
7
7
 
8
8
  AsyncFunction("prepareModel") { (_: [String: Any]?) async throws in
9
9
  if #available(iOS 26.0, *) {
10
- _ = SystemLanguageModel.default
10
+ _ = SystemLanguageModel.default
11
11
  } else {
12
12
  //
13
13
  }
@@ -18,39 +18,41 @@ public class ExpoAiKitModule: Module {
18
18
  }
19
19
 
20
20
  AsyncFunction("sendMessage") {
21
- (sessionId: String,
22
- messages: [[String: Any]],
23
- options: [String: Any]?
24
- ) async throws -> [String: Any] in
25
-
26
- let lastUser = messages
27
- .reversed()
28
- .first { ($0["role"] as? String) == "user" }?["content"] as? String
29
- ?? messages.last?["content"] as? String
30
- ?? ""
31
-
32
- if #available(iOS 26.0, *) {
33
- let systemPrompt = (messages.first {
34
- ($0["role"] as? String) == "system"
35
- }?["content"] as? String) ?? """
36
- You are a helpful, friendly assistant.
37
- Answer the user's question directly and concisely.
38
- If the question is unsafe, politely refuse, otherwise just answer.
39
- """
40
-
41
- let session = LanguageModelSession(instructions: systemPrompt)
42
-
43
- let response = try await session.respond(to: lastUser)
44
-
45
-
46
- let replyText = response.content
47
-
48
- return ["reply": replyText]
49
- } else {
50
- let replyText = "Mock reply (no on-device model): \(lastUser)"
51
- return ["reply": replyText]
52
- }
53
- }
21
+ (
22
+ sessionId: String,
23
+ messages: [[String: Any]],
24
+ options: [String: Any]?
25
+ ) async throws -> [String: Any] in
26
+
27
+ let lastUser =
28
+ messages
29
+ .reversed()
30
+ .first { ($0["role"] as? String) == "user" }?["content"] as? String
31
+ ?? messages.last?["content"] as? String
32
+ ?? ""
33
+
34
+ if #available(iOS 26.0, *) {
35
+ let systemPrompt =
36
+ (messages.first {
37
+ ($0["role"] as? String) == "system"
38
+ }?["content"] as? String) ?? """
39
+ You are a helpful, friendly assistant.
40
+ Answer the user's question directly and concisely.
41
+ If the question is unsafe, politely refuse, otherwise just answer.
42
+ """
43
+
44
+ let session = LanguageModelSession(instructions: systemPrompt)
45
+
46
+ let response = try await session.respond(to: lastUser)
47
+
48
+ let replyText = response.content
49
+
50
+ return ["reply": replyText]
51
+ } else {
52
+ let replyText = "Mock reply (no on-device model): \(lastUser)"
53
+ return ["reply": replyText]
54
+ }
55
+ }
54
56
 
55
57
  Function("isAvailable") {
56
58
  if #available(iOS 26.0, *) {
@@ -59,6 +61,59 @@ public class ExpoAiKitModule: Module {
59
61
  return false
60
62
  }
61
63
  }
64
+
65
+ AsyncFunction("sendPrompt") { (prompt: String) async throws -> String in
66
+ if #available(iOS 26.0, *) {
67
+ let systemPrompt = """
68
+ You are a helpful, knowledgeable AI assistant running privately on-device. Your responses never leave the user's device, ensuring complete privacy.
69
+
70
+ ## Core Principles
71
+ - **Accuracy first**: Provide correct, well-reasoned information. If uncertain, say so clearly rather than guessing.
72
+ - **Be genuinely helpful**: Understand the user's actual intent, not just their literal words. Anticipate follow-up needs.
73
+ - **Respect user time**: Get to the point. Lead with the answer, then provide context if needed.
74
+
75
+ ## Response Style
76
+ - Use clear, natural language—avoid jargon unless the user demonstrates technical familiarity
77
+ - Match the user's tone and complexity level
78
+ - For simple questions: give a direct answer (1-2 sentences)
79
+ - For complex topics: use structured formatting (bullet points, numbered steps, headers)
80
+ - When explaining concepts: use concrete examples and analogies
81
+ - For how-to requests: provide step-by-step instructions
82
+
83
+ ## Task Capabilities
84
+ You can help with:
85
+ - **Writing**: drafting, editing, summarizing, rephrasing, tone adjustments, grammar fixes
86
+ - **Analysis**: breaking down complex topics, comparing options, pros/cons lists
87
+ - **Brainstorming**: generating ideas, creative suggestions, alternative approaches
88
+ - **Learning**: explaining concepts, answering questions, providing examples
89
+ - **Planning**: organizing tasks, creating outlines, structuring projects
90
+ - **Problem-solving**: debugging logic, troubleshooting issues, suggesting solutions
91
+ - **Calculations**: math, unit conversions, date/time calculations
92
+ - **Code**: explaining code, writing snippets, debugging, suggesting improvements
93
+
94
+ ## Quality Standards
95
+ - Double-check facts and logic before responding
96
+ - Provide sources or reasoning when making claims
97
+ - Offer multiple perspectives on subjective topics
98
+ - Acknowledge limitations—you don't have internet access or real-time information
99
+ - If a request is ambiguous, ask a clarifying question or state your interpretation
100
+
101
+ ## Safety Boundaries
102
+ - Decline requests for harmful, illegal, dangerous, or unethical content
103
+ - Do not help with content that could endanger safety, privacy, or wellbeing
104
+ - For medical symptoms: provide general info but always recommend consulting a healthcare provider
105
+ - For legal questions: offer general guidance but recommend consulting a qualified attorney
106
+ - For financial advice: share educational information but suggest consulting a financial professional
107
+ - Do not generate content involving minors in inappropriate contexts
108
+ - Do not assist with deception, manipulation, or harassment
109
+ """
110
+
111
+ let session = LanguageModelSession(instructions: systemPrompt)
112
+ let response = try await session.respond(to: prompt)
113
+ return response.content
114
+ } else {
115
+ return "Mock reply (no on-device model): \(prompt)"
116
+ }
117
+ }
62
118
  }
63
119
  }
64
-
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-ai-kit",
3
- "version": "0.1.8",
3
+ "version": "0.1.10",
4
4
  "description": "Expo AI Kit module",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -8,9 +8,8 @@
8
8
  "build",
9
9
  "ios",
10
10
  "android",
11
- "expo-module.config.json",
12
- "README.md",
13
- "LICENSE"
11
+ "src",
12
+ "expo-module.config.json"
14
13
  ],
15
14
  "scripts": {
16
15
  "build": "expo-module build",
@@ -0,0 +1,19 @@
1
+ import { requireNativeModule } from 'expo-modules-core';
2
+ import type { LLMMessage, LLMOptions } from './types';
3
+
4
+ export type ExpoAiKitNativeModule = {
5
+ prepareModel(options?: { model?: string }): Promise<void>;
6
+ createSession(options?: { systemPrompt?: string }): Promise<string>;
7
+ sendMessage(
8
+ sessionId: string,
9
+ messages: LLMMessage[],
10
+ options?: LLMOptions
11
+ ): Promise<{ reply: string }>;
12
+ isAvailable(): boolean;
13
+ sendPrompt(prompt: string): Promise<string>;
14
+ };
15
+
16
+ const NativeModule: ExpoAiKitNativeModule =
17
+ requireNativeModule<ExpoAiKitNativeModule>('ExpoAiKit');
18
+
19
+ export default NativeModule;
package/src/index.ts ADDED
@@ -0,0 +1,34 @@
1
+ import NativeModule from './ExpoAiKitModule';
2
+ import { Platform } from 'react-native';
3
+ export * from './types';
4
+ import type { LLMMessage, LLMOptions } from './types';
5
+
6
+ export async function prepareModel(options?: { model?: string }) {
7
+ return NativeModule.prepareModel(options);
8
+ }
9
+
10
+ export async function createSession(options?: { systemPrompt?: string }) {
11
+ return NativeModule.createSession(options);
12
+ }
13
+
14
+ export async function sendMessage(
15
+ sessionId: string,
16
+ messages: LLMMessage[],
17
+ options?: LLMOptions
18
+ ) {
19
+ return NativeModule.sendMessage(sessionId, messages, options);
20
+ }
21
+
22
+ export async function isAvailable(): Promise<boolean> {
23
+ if (Platform.OS === 'ios' || Platform.OS === 'android') {
24
+ return NativeModule.isAvailable();
25
+ }
26
+ return false;
27
+ }
28
+
29
+ export async function sendPrompt(prompt: string): Promise<string> {
30
+ if (Platform.OS === 'ios' || Platform.OS === 'android') {
31
+ return NativeModule.sendPrompt(prompt);
32
+ }
33
+ return '';
34
+ }
package/src/types.ts ADDED
@@ -0,0 +1,12 @@
1
+ export type LLMRole = 'system' | 'user' | 'assistant';
2
+
3
+ export type LLMMessage = {
4
+ role: LLMRole;
5
+ content: string;
6
+ };
7
+
8
+ export type LLMOptions = {
9
+ temperature?: number;
10
+ maxTokens?: number;
11
+ model?: string;
12
+ };